00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 static BOOL next_token_internal(const char **ptr,
00041 char *buff,
00042 const char *sep,
00043 size_t bufsize,
00044 BOOL ltrim)
00045 {
00046 char *s;
00047 char *pbuf;
00048 BOOL quoted;
00049 size_t len=1;
00050
00051 if (!ptr)
00052 return(False);
00053
00054 s = (char *)*ptr;
00055
00056
00057 if (!sep)
00058 sep = " \t\n\r";
00059
00060
00061 if (ltrim) {
00062 while (*s && strchr_m(sep,*s))
00063 s++;
00064 }
00065
00066
00067 if (! *s)
00068 return(False);
00069
00070
00071 pbuf = buff;
00072 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
00073 if ( *s == '\"' ) {
00074 quoted = !quoted;
00075 } else {
00076 len++;
00077 *pbuf++ = *s;
00078 }
00079 }
00080
00081 *ptr = (*s) ? s+1 : s;
00082 *pbuf = 0;
00083
00084 return(True);
00085 }
00086
00087
00088
00089
00090
00091
00092 BOOL next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
00093 {
00094 return next_token_internal(ptr, buff, sep, bufsize, True);
00095 }
00096
00097
00098
00099
00100
00101
00102 BOOL next_token_no_ltrim(const char **ptr,
00103 char *buff,
00104 const char *sep,
00105 size_t bufsize)
00106 {
00107 return next_token_internal(ptr, buff, sep, bufsize, False);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 static const char *last_ptr=NULL;
00117
00118 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
00119 {
00120 BOOL ret;
00121 if (!ptr)
00122 ptr = &last_ptr;
00123
00124 ret = next_token(ptr, buff, sep, bufsize);
00125 last_ptr = *ptr;
00126 return ret;
00127 }
00128
00129 static uint16 tmpbuf[sizeof(pstring)];
00130
00131 void set_first_token(char *ptr)
00132 {
00133 last_ptr = ptr;
00134 }
00135
00136
00137
00138
00139
00140
00141 char **toktocliplist(int *ctok, const char *sep)
00142 {
00143 char *s=(char *)last_ptr;
00144 int ictok=0;
00145 char **ret, **iret;
00146
00147 if (!sep)
00148 sep = " \t\n\r";
00149
00150 while(*s && strchr_m(sep,*s))
00151 s++;
00152
00153
00154 if (!*s)
00155 return(NULL);
00156
00157 do {
00158 ictok++;
00159 while(*s && (!strchr_m(sep,*s)))
00160 s++;
00161 while(*s && strchr_m(sep,*s))
00162 *s++=0;
00163 } while(*s);
00164
00165 *ctok=ictok;
00166 s=(char *)last_ptr;
00167
00168 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
00169 return NULL;
00170
00171 while(ictok--) {
00172 *iret++=s;
00173 if (ictok > 0) {
00174 while(*s++)
00175 ;
00176 while(!*s)
00177 s++;
00178 }
00179 }
00180
00181 ret[*ctok] = NULL;
00182 return ret;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 int StrCaseCmp(const char *s, const char *t)
00215 {
00216
00217 const char *ps, *pt;
00218 size_t size;
00219 smb_ucs2_t *buffer_s, *buffer_t;
00220 int ret;
00221
00222 for (ps = s, pt = t; ; ps++, pt++) {
00223 char us, ut;
00224
00225 if (!*ps && !*pt)
00226 return 0;
00227 else if (!*ps)
00228 return -1;
00229 else if (!*pt)
00230 return +1;
00231 else if ((*ps & 0x80) || (*pt & 0x80))
00232
00233 break;
00234
00235 us = toupper_ascii(*ps);
00236 ut = toupper_ascii(*pt);
00237 if (us == ut)
00238 continue;
00239 else if (us < ut)
00240 return -1;
00241 else if (us > ut)
00242 return +1;
00243 }
00244
00245 size = push_ucs2_allocate(&buffer_s, ps);
00246 if (size == (size_t)-1) {
00247 return strcmp(ps, pt);
00248
00249
00250 }
00251
00252 size = push_ucs2_allocate(&buffer_t, pt);
00253 if (size == (size_t)-1) {
00254 SAFE_FREE(buffer_s);
00255 return strcmp(ps, pt);
00256
00257
00258 }
00259
00260 ret = strcasecmp_w(buffer_s, buffer_t);
00261 SAFE_FREE(buffer_s);
00262 SAFE_FREE(buffer_t);
00263 return ret;
00264 }
00265
00266
00267
00268
00269
00270 int StrnCaseCmp(const char *s, const char *t, size_t n)
00271 {
00272 pstring buf1, buf2;
00273 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
00274 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
00275 return strncmp(buf1,buf2,n);
00276 }
00277
00278
00279
00280
00281
00282
00283 BOOL strequal(const char *s1, const char *s2)
00284 {
00285 if (s1 == s2)
00286 return(True);
00287 if (!s1 || !s2)
00288 return(False);
00289
00290 return(StrCaseCmp(s1,s2)==0);
00291 }
00292
00293
00294
00295
00296
00297
00298 BOOL strnequal(const char *s1,const char *s2,size_t n)
00299 {
00300 if (s1 == s2)
00301 return(True);
00302 if (!s1 || !s2 || !n)
00303 return(False);
00304
00305 return(StrnCaseCmp(s1,s2,n)==0);
00306 }
00307
00308
00309
00310
00311
00312 BOOL strcsequal(const char *s1,const char *s2)
00313 {
00314 if (s1 == s2)
00315 return(True);
00316 if (!s1 || !s2)
00317 return(False);
00318
00319 return(strcmp(s1,s2)==0);
00320 }
00321
00322
00323
00324
00325
00326 int strwicmp(const char *psz1, const char *psz2)
00327 {
00328
00329
00330 if (psz1 == psz2)
00331 return (0);
00332 else if (psz1 == NULL)
00333 return (-1);
00334 else if (psz2 == NULL)
00335 return (1);
00336
00337
00338 while (1) {
00339 while (isspace((int)*psz1))
00340 psz1++;
00341 while (isspace((int)*psz2))
00342 psz2++;
00343 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
00344 || *psz2 == '\0')
00345 break;
00346 psz1++;
00347 psz2++;
00348 }
00349 return (*psz1 - *psz2);
00350 }
00351
00352
00353
00354
00355
00356
00357 char *strupper_static(const char *s)
00358 {
00359 static pstring str;
00360
00361 pstrcpy(str, s);
00362 strupper_m(str);
00363
00364 return str;
00365 }
00366
00367
00368
00369
00370
00371 void strnorm(char *s, int case_default)
00372 {
00373 if (case_default == CASE_UPPER)
00374 strupper_m(s);
00375 else
00376 strlower_m(s);
00377 }
00378
00379
00380
00381
00382
00383 BOOL strisnormal(const char *s, int case_default)
00384 {
00385 if (case_default == CASE_UPPER)
00386 return(!strhaslower(s));
00387
00388 return(!strhasupper(s));
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 void string_replace( char *s, char oldc, char newc )
00402 {
00403 char *p;
00404
00405
00406
00407
00408
00409
00410 for (p = s; *p; p++) {
00411 if (*p & 0x80)
00412 break;
00413 if (*p == oldc) {
00414 *p = newc;
00415 }
00416 }
00417
00418 if (!*p)
00419 return;
00420
00421
00422 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
00423
00424 p = s;
00425 #endif
00426
00427 while (*p) {
00428 size_t c_size;
00429 next_codepoint(p, &c_size);
00430
00431 if (c_size == 1) {
00432 if (*p == oldc) {
00433 *p = newc;
00434 }
00435 }
00436 p += c_size;
00437 }
00438 }
00439
00440
00441
00442
00443
00444 char *push_skip_string(char *buf)
00445 {
00446 buf += strlen(buf) + 1;
00447 return(buf);
00448 }
00449
00450
00451
00452
00453
00454
00455
00456 char *skip_string(const char *base, size_t len, char *buf)
00457 {
00458 const char *end_ptr = base + len;
00459
00460 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
00461 return NULL;
00462 }
00463
00464
00465 while (*buf) {
00466 buf++;
00467 if (buf >= end_ptr) {
00468 return NULL;
00469 }
00470 }
00471
00472 buf++;
00473 return buf;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482 size_t str_charnum(const char *s)
00483 {
00484 uint16 tmpbuf2[sizeof(pstring)];
00485 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
00486 return strlen_w(tmpbuf2);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495 size_t str_ascii_charnum(const char *s)
00496 {
00497 pstring tmpbuf2;
00498 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
00499 return strlen(tmpbuf2);
00500 }
00501
00502 BOOL trim_char(char *s,char cfront,char cback)
00503 {
00504 BOOL ret = False;
00505 char *ep;
00506 char *fp = s;
00507
00508
00509 if (!s || (s[0] == '\0'))
00510 return False;
00511
00512 if (cfront) {
00513 while (*fp && *fp == cfront)
00514 fp++;
00515 if (!*fp) {
00516
00517 s[0] = '\0';
00518 return True;
00519 }
00520 if (fp != s)
00521 ret = True;
00522 }
00523
00524 ep = fp + strlen(fp) - 1;
00525 if (cback) {
00526
00527 while ((ep >= fp) && (*ep == cback)) {
00528 ret = True;
00529 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
00530
00531 char fs[2], bs[2];
00532 if (cfront) {
00533 fs[0] = cfront;
00534 fs[1] = '\0';
00535 }
00536 bs[0] = cback;
00537 bs[1] = '\0';
00538 return trim_string(s, cfront ? fs : NULL, bs);
00539 } else {
00540 ep--;
00541 }
00542 }
00543 if (ep < fp) {
00544
00545 s[0] = '\0';
00546 return True;
00547 }
00548 }
00549
00550 ep[1] = '\0';
00551 memmove(s, fp, ep-fp+2);
00552 return ret;
00553 }
00554
00555
00556
00557
00558
00559 BOOL trim_string(char *s,const char *front,const char *back)
00560 {
00561 BOOL ret = False;
00562 size_t front_len;
00563 size_t back_len;
00564 size_t len;
00565
00566
00567 if (!s || (s[0] == '\0'))
00568 return False;
00569
00570 front_len = front? strlen(front) : 0;
00571 back_len = back? strlen(back) : 0;
00572
00573 len = strlen(s);
00574
00575 if (front_len) {
00576 while (len && strncmp(s, front, front_len)==0) {
00577
00578
00579 memmove(s, s+front_len, (len-front_len)+1);
00580 len -= front_len;
00581 ret=True;
00582 }
00583 }
00584
00585 if (back_len) {
00586 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
00587 s[len-back_len]='\0';
00588 len -= back_len;
00589 ret=True;
00590 }
00591 }
00592 return ret;
00593 }
00594
00595
00596
00597
00598
00599 BOOL strhasupper(const char *s)
00600 {
00601 smb_ucs2_t *ptr;
00602 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
00603 for(ptr=tmpbuf;*ptr;ptr++)
00604 if(isupper_w(*ptr))
00605 return True;
00606 return(False);
00607 }
00608
00609
00610
00611
00612
00613 BOOL strhaslower(const char *s)
00614 {
00615 smb_ucs2_t *ptr;
00616 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
00617 for(ptr=tmpbuf;*ptr;ptr++)
00618 if(islower_w(*ptr))
00619 return True;
00620 return(False);
00621 }
00622
00623
00624
00625
00626
00627 size_t count_chars(const char *s,char c)
00628 {
00629 smb_ucs2_t *ptr;
00630 int count;
00631 smb_ucs2_t *alloc_tmpbuf = NULL;
00632
00633 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
00634 return 0;
00635 }
00636
00637 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
00638 if(*ptr==UCS2_CHAR(c))
00639 count++;
00640
00641 SAFE_FREE(alloc_tmpbuf);
00642 return(count);
00643 }
00644
00645
00646
00647
00648
00649
00650 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
00651 {
00652 size_t len;
00653
00654 if (!dest) {
00655 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
00656 return NULL;
00657 }
00658
00659 #ifdef DEVELOPER
00660 clobber_region(fn,line,dest, maxlength+1);
00661 #endif
00662
00663 if (!src) {
00664 *dest = 0;
00665 return dest;
00666 }
00667
00668 len = strnlen(src, maxlength+1);
00669
00670 if (len > maxlength) {
00671 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
00672 (unsigned long)(len-maxlength), (unsigned long)len,
00673 (unsigned long)maxlength, src));
00674 len = maxlength;
00675 }
00676
00677 memmove(dest, src, len);
00678 dest[len] = 0;
00679 return dest;
00680 }
00681
00682
00683
00684
00685
00686 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
00687 {
00688 size_t src_len, dest_len;
00689
00690 if (!dest) {
00691 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
00692 return NULL;
00693 }
00694
00695 if (!src)
00696 return dest;
00697
00698 src_len = strnlen(src, maxlength + 1);
00699 dest_len = strnlen(dest, maxlength + 1);
00700
00701 #ifdef DEVELOPER
00702 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
00703 #endif
00704
00705 if (src_len + dest_len > maxlength) {
00706 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
00707 (int)(src_len + dest_len - maxlength), src));
00708 if (maxlength > dest_len) {
00709 memcpy(&dest[dest_len], src, maxlength - dest_len);
00710 }
00711 dest[maxlength] = 0;
00712 return NULL;
00713 }
00714
00715 memcpy(&dest[dest_len], src, src_len);
00716 dest[dest_len + src_len] = 0;
00717 return dest;
00718 }
00719
00720
00721
00722
00723
00724
00725
00726 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
00727 {
00728 size_t len, i;
00729
00730 #ifdef DEVELOPER
00731 clobber_region(fn, line, dest, maxlength);
00732 #endif
00733
00734 if (!dest) {
00735 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
00736 return NULL;
00737 }
00738
00739 if (!src) {
00740 *dest = 0;
00741 return dest;
00742 }
00743
00744 len = strlen(src);
00745 if (len >= maxlength)
00746 len = maxlength - 1;
00747
00748 if (!other_safe_chars)
00749 other_safe_chars = "";
00750
00751 for(i = 0; i < len; i++) {
00752 int val = (src[i] & 0xff);
00753 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
00754 dest[i] = src[i];
00755 else
00756 dest[i] = '_';
00757 }
00758
00759 dest[i] = '\0';
00760
00761 return dest;
00762 }
00763
00764
00765
00766
00767
00768 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
00769 {
00770 char *d = dest;
00771
00772 #ifdef DEVELOPER
00773 clobber_region(fn, line, dest, n+1);
00774 #endif
00775
00776 if (!dest) {
00777 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
00778 return(NULL);
00779 }
00780
00781 if (!src) {
00782 *dest = 0;
00783 return(dest);
00784 }
00785
00786 while (n-- && (*d = *src)) {
00787 d++;
00788 src++;
00789 }
00790
00791 *d = 0;
00792 return(dest);
00793 }
00794
00795 #if 0
00796
00797
00798
00799
00800
00801 static char *strncpyn(char *dest, const char *src, size_t n, char c)
00802 {
00803 char *p;
00804 size_t str_len;
00805
00806 #ifdef DEVELOPER
00807 clobber_region(dest, n+1);
00808 #endif
00809 p = strchr_m(src, c);
00810 if (p == NULL) {
00811 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
00812 return NULL;
00813 }
00814
00815 str_len = PTR_DIFF(p, src);
00816 strncpy(dest, src, MIN(n, str_len));
00817 dest[str_len] = '\0';
00818
00819 return p;
00820 }
00821 #endif
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 size_t strhex_to_str(char *p, size_t len, const char *strhex)
00834 {
00835 size_t i;
00836 size_t num_chars = 0;
00837 unsigned char lonybble, hinybble;
00838 const char *hexchars = "0123456789ABCDEF";
00839 char *p1 = NULL, *p2 = NULL;
00840
00841 for (i = 0; i < len && strhex[i] != 0; i++) {
00842 if (strnequal(hexchars, "0x", 2)) {
00843 i++;
00844 continue;
00845 }
00846
00847 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
00848 break;
00849
00850 i++;
00851
00852 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
00853 break;
00854
00855
00856 hinybble = PTR_DIFF(p1, hexchars);
00857 lonybble = PTR_DIFF(p2, hexchars);
00858
00859 p[num_chars] = (hinybble << 4) | lonybble;
00860 num_chars++;
00861
00862 p1 = NULL;
00863 p2 = NULL;
00864 }
00865 return num_chars;
00866 }
00867
00868 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
00869 {
00870 DATA_BLOB ret_blob;
00871
00872 if (mem_ctx != NULL)
00873 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
00874 else
00875 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
00876
00877 ret_blob.length = strhex_to_str((char*)ret_blob.data,
00878 strlen(strhex),
00879 strhex);
00880
00881 return ret_blob;
00882 }
00883
00884
00885
00886
00887
00888 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
00889 {
00890 int i;
00891 char *hex_buffer;
00892
00893 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
00894
00895 for (i = 0; i < len; i++)
00896 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
00897
00898 return hex_buffer;
00899 }
00900
00901
00902
00903
00904
00905 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
00906 {
00907 pstring tok;
00908 const char *p=list;
00909
00910 if (!list)
00911 return(False);
00912
00913 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
00914 if (casesensitive) {
00915 if (strcmp(tok,s) == 0)
00916 return(True);
00917 } else {
00918 if (StrCaseCmp(tok,s) == 0)
00919 return(True);
00920 }
00921 }
00922 return(False);
00923 }
00924
00925
00926 static const char *null_string = "";
00927
00928
00929
00930
00931
00932 static BOOL string_init(char **dest,const char *src)
00933 {
00934 size_t l;
00935
00936 if (!src)
00937 src = "";
00938
00939 l = strlen(src);
00940
00941 if (l == 0) {
00942 *dest = CONST_DISCARD(char*, null_string);
00943 } else {
00944 (*dest) = SMB_STRDUP(src);
00945 if ((*dest) == NULL) {
00946 DEBUG(0,("Out of memory in string_init\n"));
00947 return False;
00948 }
00949 }
00950 return(True);
00951 }
00952
00953
00954
00955
00956
00957 void string_free(char **s)
00958 {
00959 if (!s || !(*s))
00960 return;
00961 if (*s == null_string)
00962 *s = NULL;
00963 SAFE_FREE(*s);
00964 }
00965
00966
00967
00968
00969
00970
00971 BOOL string_set(char **dest,const char *src)
00972 {
00973 string_free(dest);
00974 return(string_init(dest,src));
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
00990 BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
00991 {
00992 char *p;
00993 ssize_t ls,lp,li, i;
00994
00995 if (!insert || !pattern || !*pattern || !s)
00996 return;
00997
00998 ls = (ssize_t)strlen(s);
00999 lp = (ssize_t)strlen(pattern);
01000 li = (ssize_t)strlen(insert);
01001
01002 if (len == 0)
01003 len = ls + 1;
01004
01005 while (lp <= ls && (p = strstr_m(s,pattern))) {
01006 if (ls + (li-lp) >= len) {
01007 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
01008 (int)(ls + (li-lp) - len),
01009 pattern, (int)len));
01010 break;
01011 }
01012 if (li != lp) {
01013 memmove(p+li,p+lp,strlen(p+lp)+1);
01014 }
01015 for (i=0;i<li;i++) {
01016 switch (insert[i]) {
01017 case '`':
01018 case '"':
01019 case '\'':
01020 case ';':
01021 case '$':
01022
01023 if (allow_trailing_dollar && (i == li - 1 )) {
01024 p[i] = insert[i];
01025 break;
01026 }
01027 case '%':
01028 case '\r':
01029 case '\n':
01030 if ( remove_unsafe_characters ) {
01031 p[i] = '_';
01032
01033
01034 break;
01035 }
01036 default:
01037 p[i] = insert[i];
01038 }
01039 }
01040 s = p + li;
01041 ls += (li-lp);
01042
01043 if (replace_once)
01044 break;
01045 }
01046 }
01047
01048 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
01049 {
01050 string_sub2( s, pattern, insert, len, True, True, False );
01051 }
01052
01053 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
01054 {
01055 string_sub2( s, pattern, insert, len, True, False, False );
01056 }
01057
01058 void fstring_sub(char *s,const char *pattern,const char *insert)
01059 {
01060 string_sub(s, pattern, insert, sizeof(fstring));
01061 }
01062
01063 void pstring_sub(char *s,const char *pattern,const char *insert)
01064 {
01065 string_sub(s, pattern, insert, sizeof(pstring));
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075 char *realloc_string_sub(char *string, const char *pattern,
01076 const char *insert)
01077 {
01078 char *p, *in;
01079 char *s;
01080 ssize_t ls,lp,li,ld, i;
01081
01082 if (!insert || !pattern || !*pattern || !string || !*string)
01083 return NULL;
01084
01085 s = string;
01086
01087 in = SMB_STRDUP(insert);
01088 if (!in) {
01089 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
01090 return NULL;
01091 }
01092 ls = (ssize_t)strlen(s);
01093 lp = (ssize_t)strlen(pattern);
01094 li = (ssize_t)strlen(insert);
01095 ld = li - lp;
01096 for (i=0;i<li;i++) {
01097 switch (in[i]) {
01098 case '`':
01099 case '"':
01100 case '\'':
01101 case ';':
01102 case '$':
01103 case '%':
01104 case '\r':
01105 case '\n':
01106 in[i] = '_';
01107 default:
01108
01109 break;
01110 }
01111 }
01112
01113 while ((p = strstr_m(s,pattern))) {
01114 if (ld > 0) {
01115 int offset = PTR_DIFF(s,string);
01116 string = (char *)SMB_REALLOC(string, ls + ld + 1);
01117 if (!string) {
01118 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
01119 SAFE_FREE(in);
01120 return NULL;
01121 }
01122 p = string + offset + (p - s);
01123 }
01124 if (li != lp) {
01125 memmove(p+li,p+lp,strlen(p+lp)+1);
01126 }
01127 memcpy(p, in, li);
01128 s = p + li;
01129 ls += ld;
01130 }
01131 SAFE_FREE(in);
01132 return string;
01133 }
01134
01135
01136
01137 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
01138 const char *pattern, const char *insert)
01139 {
01140 char *p, *in;
01141 char *s;
01142 char *string;
01143 ssize_t ls,lp,li,ld, i;
01144
01145 if (!insert || !pattern || !*pattern || !src || !*src)
01146 return NULL;
01147
01148 string = talloc_strdup(mem_ctx, src);
01149 if (string == NULL) {
01150 DEBUG(0, ("talloc_strdup failed\n"));
01151 return NULL;
01152 }
01153
01154 s = string;
01155
01156 in = SMB_STRDUP(insert);
01157 if (!in) {
01158 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
01159 return NULL;
01160 }
01161 ls = (ssize_t)strlen(s);
01162 lp = (ssize_t)strlen(pattern);
01163 li = (ssize_t)strlen(insert);
01164 ld = li - lp;
01165 for (i=0;i<li;i++) {
01166 switch (in[i]) {
01167 case '`':
01168 case '"':
01169 case '\'':
01170 case ';':
01171 case '$':
01172 case '%':
01173 case '\r':
01174 case '\n':
01175 in[i] = '_';
01176 default:
01177
01178 break;
01179 }
01180 }
01181
01182 while ((p = strstr_m(s,pattern))) {
01183 if (ld > 0) {
01184 int offset = PTR_DIFF(s,string);
01185 string = (char *)TALLOC_REALLOC(mem_ctx, string,
01186 ls + ld + 1);
01187 if (!string) {
01188 DEBUG(0, ("talloc_string_sub: out of "
01189 "memory!\n"));
01190 SAFE_FREE(in);
01191 return NULL;
01192 }
01193 p = string + offset + (p - s);
01194 }
01195 if (li != lp) {
01196 memmove(p+li,p+lp,strlen(p+lp)+1);
01197 }
01198 memcpy(p, in, li);
01199 s = p + li;
01200 ls += ld;
01201 }
01202 SAFE_FREE(in);
01203 return string;
01204 }
01205
01206
01207
01208
01209
01210
01211
01212
01213 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
01214 {
01215 char *p;
01216 ssize_t ls,lp,li;
01217
01218 if (!insert || !pattern || !s)
01219 return;
01220
01221 ls = (ssize_t)strlen(s);
01222 lp = (ssize_t)strlen(pattern);
01223 li = (ssize_t)strlen(insert);
01224
01225 if (!*pattern)
01226 return;
01227
01228 if (len == 0)
01229 len = ls + 1;
01230
01231 while (lp <= ls && (p = strstr_m(s,pattern))) {
01232 if (ls + (li-lp) >= len) {
01233 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
01234 (int)(ls + (li-lp) - len),
01235 pattern, (int)len));
01236 break;
01237 }
01238 if (li != lp) {
01239 memmove(p+li,p+lp,strlen(p+lp)+1);
01240 }
01241 memcpy(p, insert, li);
01242 s = p + li;
01243 ls += (li-lp);
01244 }
01245 }
01246
01247
01248
01249
01250
01251
01252
01253
01254 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
01255 const smb_ucs2_t *insert)
01256 {
01257 smb_ucs2_t *r, *rp;
01258 const smb_ucs2_t *sp;
01259 size_t lr, lp, li, lt;
01260
01261 if (!insert || !pattern || !*pattern || !s)
01262 return NULL;
01263
01264 lt = (size_t)strlen_w(s);
01265 lp = (size_t)strlen_w(pattern);
01266 li = (size_t)strlen_w(insert);
01267
01268 if (li > lp) {
01269 const smb_ucs2_t *st = s;
01270 int ld = li - lp;
01271 while ((sp = strstr_w(st, pattern))) {
01272 st = sp + lp;
01273 lt += ld;
01274 }
01275 }
01276
01277 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
01278 if (!r) {
01279 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
01280 return NULL;
01281 }
01282
01283 while ((sp = strstr_w(s, pattern))) {
01284 memcpy(rp, s, (sp - s));
01285 rp += ((sp - s) / sizeof(smb_ucs2_t));
01286 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
01287 s = sp + lp;
01288 rp += li;
01289 }
01290 lr = ((rp - r) / sizeof(smb_ucs2_t));
01291 if (lr < lt) {
01292 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
01293 rp += (lt - lr);
01294 }
01295 *rp = 0;
01296
01297 return r;
01298 }
01299
01300 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
01301 const char *insert)
01302 {
01303 wpstring p, i;
01304
01305 if (!insert || !pattern || !s)
01306 return NULL;
01307 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
01308 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
01309 return all_string_sub_w(s, p, i);
01310 }
01311
01312 #if 0
01313
01314
01315
01316
01317 static void split_at_last_component(char *path, char *front, char sep, char *back)
01318 {
01319 char *p = strrchr_m(path, sep);
01320
01321 if (p != NULL)
01322 *p = 0;
01323
01324 if (front != NULL)
01325 pstrcpy(front, path);
01326
01327 if (p != NULL) {
01328 if (back != NULL)
01329 pstrcpy(back, p+1);
01330 *p = '\\';
01331 } else {
01332 if (back != NULL)
01333 back[0] = 0;
01334 }
01335 }
01336 #endif
01337
01338
01339
01340
01341
01342 const char *octal_string(int i)
01343 {
01344 static char ret[64];
01345 if (i == -1)
01346 return "-1";
01347 slprintf(ret, sizeof(ret)-1, "0%o", i);
01348 return ret;
01349 }
01350
01351
01352
01353
01354
01355
01356 char *string_truncate(char *s, unsigned int length)
01357 {
01358 if (s && strlen(s) > length)
01359 s[length] = 0;
01360 return s;
01361 }
01362
01363
01364
01365
01366
01367
01368 char *strchr_m(const char *src, char c)
01369 {
01370 wpstring ws;
01371 pstring s2;
01372 smb_ucs2_t *p;
01373 const char *s;
01374
01375
01376
01377 if ((c & 0xC0) == 0) {
01378 return strchr(src, c);
01379 }
01380
01381
01382
01383
01384
01385
01386 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
01387 if (*s == c)
01388 return (char *)s;
01389 }
01390
01391 if (!*s)
01392 return NULL;
01393
01394 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
01395
01396 s = src;
01397 #endif
01398
01399 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
01400 p = strchr_w(ws, UCS2_CHAR(c));
01401 if (!p)
01402 return NULL;
01403 *p = 0;
01404 pull_ucs2_pstring(s2, ws);
01405 return (char *)(s+strlen(s2));
01406 }
01407
01408 char *strrchr_m(const char *s, char c)
01409 {
01410
01411
01412 if ((c & 0xC0) == 0) {
01413 return strrchr(s, c);
01414 }
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425 {
01426 size_t len = strlen(s);
01427 const char *cp = s;
01428 BOOL got_mb = False;
01429
01430 if (len == 0)
01431 return NULL;
01432 cp += (len - 1);
01433 do {
01434 if (c == *cp) {
01435
01436 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
01437
01438 got_mb = True;
01439 break;
01440 }
01441
01442 return (char *)cp;
01443 }
01444 } while (cp-- != s);
01445 if (!got_mb)
01446 return NULL;
01447 }
01448
01449
01450 {
01451 wpstring ws;
01452 pstring s2;
01453 smb_ucs2_t *p;
01454
01455 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
01456 p = strrchr_w(ws, UCS2_CHAR(c));
01457 if (!p)
01458 return NULL;
01459 *p = 0;
01460 pull_ucs2_pstring(s2, ws);
01461 return (char *)(s+strlen(s2));
01462 }
01463 }
01464
01465
01466
01467
01468
01469
01470 char *strnrchr_m(const char *s, char c, unsigned int n)
01471 {
01472 wpstring ws;
01473 pstring s2;
01474 smb_ucs2_t *p;
01475
01476 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
01477 p = strnrchr_w(ws, UCS2_CHAR(c), n);
01478 if (!p)
01479 return NULL;
01480 *p = 0;
01481 pull_ucs2_pstring(s2, ws);
01482 return (char *)(s+strlen(s2));
01483 }
01484
01485
01486
01487
01488
01489 char *strstr_m(const char *src, const char *findstr)
01490 {
01491 smb_ucs2_t *p;
01492 smb_ucs2_t *src_w, *find_w;
01493 const char *s;
01494 char *s2;
01495 char *retp;
01496
01497 size_t findstr_len = 0;
01498
01499
01500 if (!findstr[0]) {
01501 return (char*)src;
01502 }
01503
01504
01505 if (findstr[1] == '\0')
01506 return strchr_m(src, *findstr);
01507
01508
01509
01510
01511
01512 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
01513 if (*s == *findstr) {
01514 if (!findstr_len)
01515 findstr_len = strlen(findstr);
01516
01517 if (strncmp(s, findstr, findstr_len) == 0) {
01518 return (char *)s;
01519 }
01520 }
01521 }
01522
01523 if (!*s)
01524 return NULL;
01525
01526 #if 1
01527
01528
01529
01530 s = src;
01531 #endif
01532
01533 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
01534 DEBUG(0,("strstr_m: src malloc fail\n"));
01535 return NULL;
01536 }
01537
01538 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
01539 SAFE_FREE(src_w);
01540 DEBUG(0,("strstr_m: find malloc fail\n"));
01541 return NULL;
01542 }
01543
01544 p = strstr_w(src_w, find_w);
01545
01546 if (!p) {
01547 SAFE_FREE(src_w);
01548 SAFE_FREE(find_w);
01549 return NULL;
01550 }
01551
01552 *p = 0;
01553 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
01554 SAFE_FREE(src_w);
01555 SAFE_FREE(find_w);
01556 DEBUG(0,("strstr_m: dest malloc fail\n"));
01557 return NULL;
01558 }
01559 retp = (char *)(s+strlen(s2));
01560 SAFE_FREE(src_w);
01561 SAFE_FREE(find_w);
01562 SAFE_FREE(s2);
01563 return retp;
01564 }
01565
01566
01567
01568
01569
01570 void strlower_m(char *s)
01571 {
01572 size_t len;
01573 int errno_save;
01574
01575
01576
01577
01578
01579
01580 while (*s && !(((unsigned char)s[0]) & 0x80)) {
01581 *s = tolower_ascii((unsigned char)*s);
01582 s++;
01583 }
01584
01585 if (!*s)
01586 return;
01587
01588
01589
01590 len = strlen(s) + 1;
01591 errno_save = errno;
01592 errno = 0;
01593 unix_strlower(s,len,s,len);
01594
01595 if (errno)
01596 s[len-1] = '\0';
01597 errno = errno_save;
01598 }
01599
01600
01601
01602
01603
01604 void strupper_m(char *s)
01605 {
01606 size_t len;
01607 int errno_save;
01608
01609
01610
01611
01612
01613
01614 while (*s && !(((unsigned char)s[0]) & 0x80)) {
01615 *s = toupper_ascii((unsigned char)*s);
01616 s++;
01617 }
01618
01619 if (!*s)
01620 return;
01621
01622
01623
01624 len = strlen(s) + 1;
01625 errno_save = errno;
01626 errno = 0;
01627 unix_strupper(s,len,s,len);
01628
01629 if (errno)
01630 s[len-1] = '\0';
01631 errno = errno_save;
01632 }
01633
01634
01635
01636
01637
01638
01639
01640 size_t strlen_m(const char *s)
01641 {
01642 size_t count = 0;
01643
01644 if (!s) {
01645 return 0;
01646 }
01647
01648 while (*s && !(((uint8_t)*s) & 0x80)) {
01649 s++;
01650 count++;
01651 }
01652
01653 if (!*s) {
01654 return count;
01655 }
01656
01657 while (*s) {
01658 size_t c_size;
01659 codepoint_t c = next_codepoint(s, &c_size);
01660 if (c < 0x10000) {
01661
01662 count += 1;
01663 } else {
01664
01665 count += 2;
01666 }
01667 s += c_size;
01668 }
01669
01670 return count;
01671 }
01672
01673
01674
01675
01676
01677
01678 size_t strlen_m_term(const char *s)
01679 {
01680 if (!s) {
01681 return 0;
01682 }
01683 return strlen_m(s) + 1;
01684 }
01685
01686
01687
01688
01689
01690
01691 size_t strlen_m_term_null(const char *s)
01692 {
01693 size_t len;
01694 if (!s) {
01695 return 0;
01696 }
01697 len = strlen_m(s);
01698 if (len == 0) {
01699 return 0;
01700 }
01701
01702 return len+1;
01703 }
01704
01705
01706
01707
01708
01709
01710 char *binary_string_rfc2254(char *buf, int len)
01711 {
01712 char *s;
01713 int i, j;
01714 const char *hex = "0123456789ABCDEF";
01715 s = (char *)SMB_MALLOC(len * 3 + 1);
01716 if (!s)
01717 return NULL;
01718 for (j=i=0;i<len;i++) {
01719 s[j] = '\\';
01720 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
01721 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
01722 j += 3;
01723 }
01724 s[j] = 0;
01725 return s;
01726 }
01727
01728 char *binary_string(char *buf, int len)
01729 {
01730 char *s;
01731 int i, j;
01732 const char *hex = "0123456789ABCDEF";
01733 s = (char *)SMB_MALLOC(len * 2 + 1);
01734 if (!s)
01735 return NULL;
01736 for (j=i=0;i<len;i++) {
01737 s[j] = hex[((unsigned char)buf[i]) >> 4];
01738 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
01739 j += 2;
01740 }
01741 s[j] = 0;
01742 return s;
01743 }
01744
01745
01746
01747
01748 int pstr_sprintf(pstring s, const char *fmt, ...)
01749 {
01750 va_list ap;
01751 int ret;
01752
01753 va_start(ap, fmt);
01754 ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
01755 va_end(ap);
01756 return ret;
01757 }
01758
01759
01760
01761
01762
01763
01764 int fstr_sprintf(fstring s, const char *fmt, ...)
01765 {
01766 va_list ap;
01767 int ret;
01768
01769 va_start(ap, fmt);
01770 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
01771 va_end(ap);
01772 return ret;
01773 }
01774
01775
01776
01777
01778
01779 #define S_LIST_ABS 16
01780
01781 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
01782 {
01783 char **list, **rlist;
01784 const char *str;
01785 char *s;
01786 int num, lsize;
01787 pstring tok;
01788
01789 if (!string || !*string)
01790 return NULL;
01791 if (mem_ctx) {
01792 s = talloc_strdup(mem_ctx, string);
01793 } else {
01794 s = SMB_STRDUP(string);
01795 }
01796 if (!s) {
01797 DEBUG(0,("str_list_make: Unable to allocate memory"));
01798 return NULL;
01799 }
01800 if (!sep) sep = LIST_SEP;
01801
01802 num = lsize = 0;
01803 list = NULL;
01804
01805 str = s;
01806 while (next_token(&str, tok, sep, sizeof(tok))) {
01807 if (num == lsize) {
01808 lsize += S_LIST_ABS;
01809 if (mem_ctx) {
01810 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
01811 } else {
01812
01813
01814 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
01815 }
01816 if (!rlist) {
01817 DEBUG(0,("str_list_make: Unable to allocate memory"));
01818 str_list_free(&list);
01819 if (mem_ctx) {
01820 TALLOC_FREE(s);
01821 } else {
01822 SAFE_FREE(s);
01823 }
01824 return NULL;
01825 } else {
01826 list = rlist;
01827 }
01828 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
01829 }
01830
01831 if (mem_ctx) {
01832 list[num] = talloc_strdup(mem_ctx, tok);
01833 } else {
01834 list[num] = SMB_STRDUP(tok);
01835 }
01836
01837 if (!list[num]) {
01838 DEBUG(0,("str_list_make: Unable to allocate memory"));
01839 str_list_free(&list);
01840 if (mem_ctx) {
01841 TALLOC_FREE(s);
01842 } else {
01843 SAFE_FREE(s);
01844 }
01845 return NULL;
01846 }
01847
01848 num++;
01849 }
01850
01851 if (mem_ctx) {
01852 TALLOC_FREE(s);
01853 } else {
01854 SAFE_FREE(s);
01855 }
01856
01857 return list;
01858 }
01859
01860 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
01861 {
01862 return str_list_make_internal(mem_ctx, string, sep);
01863 }
01864
01865 char **str_list_make(const char *string, const char *sep)
01866 {
01867 return str_list_make_internal(NULL, string, sep);
01868 }
01869
01870 BOOL str_list_copy(char ***dest, const char **src)
01871 {
01872 char **list, **rlist;
01873 int num, lsize;
01874
01875 *dest = NULL;
01876 if (!src)
01877 return False;
01878
01879 num = lsize = 0;
01880 list = NULL;
01881
01882 while (src[num]) {
01883 if (num == lsize) {
01884 lsize += S_LIST_ABS;
01885 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
01886 if (!rlist) {
01887 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
01888 str_list_free(&list);
01889 return False;
01890 } else {
01891 list = rlist;
01892 }
01893 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
01894 }
01895
01896 list[num] = SMB_STRDUP(src[num]);
01897 if (!list[num]) {
01898 DEBUG(0,("str_list_copy: Unable to allocate memory"));
01899 str_list_free(&list);
01900 return False;
01901 }
01902
01903 num++;
01904 }
01905
01906 *dest = list;
01907 return True;
01908 }
01909
01910
01911
01912
01913 BOOL str_list_compare(char **list1, char **list2)
01914 {
01915 int num;
01916
01917 if (!list1 || !list2)
01918 return (list1 == list2);
01919
01920 for (num = 0; list1[num]; num++) {
01921 if (!list2[num])
01922 return False;
01923 if (!strcsequal(list1[num], list2[num]))
01924 return False;
01925 }
01926 if (list2[num])
01927 return False;
01928
01929 return True;
01930 }
01931
01932 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
01933 {
01934 char **tlist;
01935
01936 if (!list || !*list)
01937 return;
01938 tlist = *list;
01939 for(; *tlist; tlist++) {
01940 if (mem_ctx) {
01941 TALLOC_FREE(*tlist);
01942 } else {
01943 SAFE_FREE(*tlist);
01944 }
01945 }
01946 if (mem_ctx) {
01947 TALLOC_FREE(*tlist);
01948 } else {
01949 SAFE_FREE(*list);
01950 }
01951 }
01952
01953 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
01954 {
01955 str_list_free_internal(mem_ctx, list);
01956 }
01957
01958 void str_list_free(char ***list)
01959 {
01960 str_list_free_internal(NULL, list);
01961 }
01962
01963
01964
01965
01966 int str_list_count( const char **list )
01967 {
01968 int i = 0;
01969
01970 if ( ! list )
01971 return 0;
01972
01973
01974
01975 for ( i=0; *list; i++, list++ );
01976
01977 return i;
01978 }
01979
01980
01981
01982
01983
01984
01985 BOOL str_list_sub_basic( char **list, const char *smb_name,
01986 const char *domain_name )
01987 {
01988 char *s, *tmpstr;
01989
01990 while ( *list ) {
01991 s = *list;
01992 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
01993 if ( !tmpstr ) {
01994 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
01995 return False;
01996 }
01997
01998 SAFE_FREE(*list);
01999 *list = tmpstr;
02000
02001 list++;
02002 }
02003
02004 return True;
02005 }
02006
02007
02008
02009
02010
02011 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
02012 {
02013 char *p, *s, *t;
02014 ssize_t ls, lp, li, ld, i, d;
02015
02016 if (!list)
02017 return False;
02018 if (!pattern)
02019 return False;
02020 if (!insert)
02021 return False;
02022
02023 lp = (ssize_t)strlen(pattern);
02024 li = (ssize_t)strlen(insert);
02025 ld = li -lp;
02026
02027 while (*list) {
02028 s = *list;
02029 ls = (ssize_t)strlen(s);
02030
02031 while ((p = strstr_m(s, pattern))) {
02032 t = *list;
02033 d = p -t;
02034 if (ld) {
02035 t = (char *) SMB_MALLOC(ls +ld +1);
02036 if (!t) {
02037 DEBUG(0,("str_list_substitute: Unable to allocate memory"));
02038 return False;
02039 }
02040 memcpy(t, *list, d);
02041 memcpy(t +d +li, p +lp, ls -d -lp +1);
02042 SAFE_FREE(*list);
02043 *list = t;
02044 ls += ld;
02045 s = t +d +li;
02046 }
02047
02048 for (i = 0; i < li; i++) {
02049 switch (insert[i]) {
02050 case '`':
02051 case '"':
02052 case '\'':
02053 case ';':
02054 case '$':
02055 case '%':
02056 case '\r':
02057 case '\n':
02058 t[d +i] = '_';
02059 break;
02060 default:
02061 t[d +i] = insert[i];
02062 }
02063 }
02064 }
02065
02066
02067 list++;
02068 }
02069
02070 return True;
02071 }
02072
02073
02074 #define IPSTR_LIST_SEP ","
02075 #define IPSTR_LIST_CHAR ','
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
02091 {
02092 char* new_ipstr = NULL;
02093
02094
02095 if (!ipstr_list || !service) return NULL;
02096
02097
02098 if (*ipstr_list) {
02099 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
02100 inet_ntoa(service->ip), service->port);
02101 SAFE_FREE(*ipstr_list);
02102 } else {
02103 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
02104 }
02105 *ipstr_list = new_ipstr;
02106 return *ipstr_list;
02107 }
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
02121 {
02122 int i;
02123
02124
02125 if (!ip_list || !ipstr_list) return 0;
02126
02127 *ipstr_list = NULL;
02128
02129
02130 for (i = 0; i < ip_count; i++)
02131 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
02132
02133 return (*ipstr_list);
02134 }
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
02149 {
02150 fstring token_str;
02151 size_t count;
02152 int i;
02153
02154 if (!ipstr_list || !ip_list)
02155 return 0;
02156
02157 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
02158 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
02159 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
02160 return 0;
02161 }
02162
02163 for ( i=0;
02164 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
02165 i++ )
02166 {
02167 struct in_addr addr;
02168 unsigned port = 0;
02169 char *p = strchr(token_str, ':');
02170
02171 if (p) {
02172 *p = 0;
02173 port = atoi(p+1);
02174 }
02175
02176
02177 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
02178 break;
02179
02180 (*ip_list)[i].ip = addr;
02181 (*ip_list)[i].port = port;
02182 }
02183
02184 return count;
02185 }
02186
02187
02188
02189
02190
02191
02192
02193
02194 void ipstr_list_free(char* ipstr_list)
02195 {
02196 SAFE_FREE(ipstr_list);
02197 }
02198
02199
02200
02201
02202
02203
02204 void rfc1738_unescape(char *buf)
02205 {
02206 char *p=buf;
02207
02208 while (p && *p && (p=strchr_m(p,'%'))) {
02209 int c1 = p[1];
02210 int c2 = p[2];
02211
02212 if (c1 >= '0' && c1 <= '9')
02213 c1 = c1 - '0';
02214 else if (c1 >= 'A' && c1 <= 'F')
02215 c1 = 10 + c1 - 'A';
02216 else if (c1 >= 'a' && c1 <= 'f')
02217 c1 = 10 + c1 - 'a';
02218 else {p++; continue;}
02219
02220 if (c2 >= '0' && c2 <= '9')
02221 c2 = c2 - '0';
02222 else if (c2 >= 'A' && c2 <= 'F')
02223 c2 = 10 + c2 - 'A';
02224 else if (c2 >= 'a' && c2 <= 'f')
02225 c2 = 10 + c2 - 'a';
02226 else {p++; continue;}
02227
02228 *p = (c1<<4) | c2;
02229
02230 memmove(p+1, p+3, strlen(p+3)+1);
02231 p++;
02232 }
02233 }
02234
02235 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
02236
02237
02238
02239
02240 DATA_BLOB base64_decode_data_blob(const char *s)
02241 {
02242 int bit_offset, byte_offset, idx, i, n;
02243 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
02244 unsigned char *d = decoded.data;
02245 char *p;
02246
02247 n=i=0;
02248
02249 while (*s && (p=strchr_m(b64,*s))) {
02250 idx = (int)(p - b64);
02251 byte_offset = (i*6)/8;
02252 bit_offset = (i*6)%8;
02253 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
02254 if (bit_offset < 3) {
02255 d[byte_offset] |= (idx << (2-bit_offset));
02256 n = byte_offset+1;
02257 } else {
02258 d[byte_offset] |= (idx >> (bit_offset-2));
02259 d[byte_offset+1] = 0;
02260 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
02261 n = byte_offset+2;
02262 }
02263 s++; i++;
02264 }
02265
02266 if ((n > 0) && (*s == '=')) {
02267 n -= 1;
02268 }
02269
02270
02271 decoded.length = n;
02272 return decoded;
02273 }
02274
02275
02276
02277
02278 void base64_decode_inplace(char *s)
02279 {
02280 DATA_BLOB decoded = base64_decode_data_blob(s);
02281
02282 if ( decoded.length != 0 ) {
02283 memcpy(s, decoded.data, decoded.length);
02284
02285
02286 s[decoded.length] = '\0';
02287 } else {
02288 *s = '\0';
02289 }
02290
02291 data_blob_free(&decoded);
02292 }
02293
02294
02295
02296
02297
02298
02299 char * base64_encode_data_blob(DATA_BLOB data)
02300 {
02301 int bits = 0;
02302 int char_count = 0;
02303 size_t out_cnt, len, output_len;
02304 char *result;
02305
02306 if (!data.length || !data.data)
02307 return NULL;
02308
02309 out_cnt = 0;
02310 len = data.length;
02311 output_len = data.length * 2 + 4;
02312
02313
02314 result = (char *)SMB_MALLOC(output_len);
02315
02316 while (len-- && out_cnt < (data.length * 2) - 5) {
02317 int c = (unsigned char) *(data.data++);
02318 bits += c;
02319 char_count++;
02320 if (char_count == 3) {
02321 result[out_cnt++] = b64[bits >> 18];
02322 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
02323 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
02324 result[out_cnt++] = b64[bits & 0x3f];
02325 bits = 0;
02326 char_count = 0;
02327 } else {
02328 bits <<= 8;
02329 }
02330 }
02331 if (char_count != 0) {
02332 bits <<= 16 - (8 * char_count);
02333 result[out_cnt++] = b64[bits >> 18];
02334 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
02335 if (char_count == 1) {
02336 result[out_cnt++] = '=';
02337 result[out_cnt++] = '=';
02338 } else {
02339 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
02340 result[out_cnt++] = '=';
02341 }
02342 }
02343 result[out_cnt] = '\0';
02344 return result;
02345 }
02346
02347
02348 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
02349 {
02350
02351 SMB_BIG_UINT val = -1;
02352 const char *p = nptr;
02353
02354 if (!p) {
02355 if (entptr) {
02356 *entptr = p;
02357 }
02358 return val;
02359 }
02360
02361 while (*p && isspace(*p))
02362 p++;
02363
02364 #ifdef LARGE_SMB_OFF_T
02365 sscanf(p,"%llu",&val);
02366 #else
02367 sscanf(p,"%lu",&val);
02368 #endif
02369 if (entptr) {
02370 while (*p && isdigit(*p))
02371 p++;
02372 *entptr = p;
02373 }
02374
02375 return val;
02376 }
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389 SMB_OFF_T conv_str_size(const char * str)
02390 {
02391 SMB_OFF_T lval;
02392 char * end;
02393
02394 if (str == NULL || *str == '\0') {
02395 return 0;
02396 }
02397
02398 #ifdef HAVE_STRTOULL
02399 if (sizeof(SMB_OFF_T) == 8) {
02400 lval = strtoull(str, &end, 10 );
02401 } else {
02402 lval = strtoul(str, &end, 10 );
02403 }
02404 #else
02405 lval = strtoul(str, &end, 10 );
02406 #endif
02407
02408 if (end == NULL || end == str) {
02409 return 0;
02410 }
02411
02412 if (*end) {
02413 SMB_OFF_T lval_orig = lval;
02414
02415 if (strwicmp(end, "K") == 0) {
02416 lval *= (SMB_OFF_T)1024;
02417 } else if (strwicmp(end, "M") == 0) {
02418 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
02419 } else if (strwicmp(end, "G") == 0) {
02420 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
02421 (SMB_OFF_T)1024);
02422 } else if (strwicmp(end, "T") == 0) {
02423 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
02424 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
02425 } else if (strwicmp(end, "P") == 0) {
02426 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
02427 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
02428 (SMB_OFF_T)1024);
02429 } else {
02430 return 0;
02431 }
02432
02433
02434
02435
02436
02437 if (lval_orig <= lval) {
02438 return 0;
02439 }
02440 }
02441
02442 return lval;
02443 }
02444
02445 void string_append(char **left, const char *right)
02446 {
02447 int new_len = strlen(right) + 1;
02448
02449 if (*left == NULL) {
02450 *left = (char *)SMB_MALLOC(new_len);
02451 *left[0] = '\0';
02452 } else {
02453 new_len += strlen(*left);
02454 *left = (char *)SMB_REALLOC(*left, new_len);
02455 }
02456
02457 if (*left == NULL) {
02458 return;
02459 }
02460
02461 safe_strcat(*left, right, new_len-1);
02462 }
02463
02464 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
02465 const char *str, const char ***strings,
02466 int *num)
02467 {
02468 char *dup_str = talloc_strdup(mem_ctx, str);
02469
02470 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
02471
02472 if ((*strings == NULL) || (dup_str == NULL)) {
02473 *num = 0;
02474 return False;
02475 }
02476
02477 (*strings)[*num] = dup_str;
02478 *num += 1;
02479 return True;
02480 }
02481
02482
02483
02484
02485
02486 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
02487 size_t *bufsize, const char *fmt, ...)
02488 {
02489 va_list ap;
02490 char *newstr;
02491 int ret;
02492 BOOL increased;
02493
02494
02495 if (*len < 0)
02496 goto error;
02497
02498 if (*string == NULL) {
02499 if (*bufsize == 0)
02500 *bufsize = 128;
02501
02502 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
02503 if (*string == NULL)
02504 goto error;
02505 }
02506
02507 va_start(ap, fmt);
02508 ret = vasprintf(&newstr, fmt, ap);
02509 va_end(ap);
02510
02511 if (ret < 0)
02512 goto error;
02513
02514 increased = False;
02515
02516 while ((*len)+ret >= *bufsize) {
02517 increased = True;
02518 *bufsize *= 2;
02519 if (*bufsize >= (1024*1024*256))
02520 goto error;
02521 }
02522
02523 if (increased) {
02524 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
02525 *bufsize);
02526 if (*string == NULL) {
02527 goto error;
02528 }
02529 }
02530
02531 StrnCpy((*string)+(*len), newstr, ret);
02532 (*len) += ret;
02533 free(newstr);
02534 return;
02535
02536 error:
02537 *len = -1;
02538 *string = NULL;
02539 }
02540
02541
02542
02543
02544
02545
02546
02547 char *sstring_sub(const char *src, char front, char back)
02548 {
02549 char *temp1, *temp2, *temp3;
02550 ptrdiff_t len;
02551
02552 temp1 = strchr(src, front);
02553 if (temp1 == NULL) return NULL;
02554 temp2 = strchr(src, back);
02555 if (temp2 == NULL) return NULL;
02556 len = temp2 - temp1;
02557 if (len <= 0) return NULL;
02558 temp3 = (char*)SMB_MALLOC(len);
02559 if (temp3 == NULL) {
02560 DEBUG(1,("Malloc failure in sstring_sub\n"));
02561 return NULL;
02562 }
02563 memcpy(temp3, temp1+1, len-1);
02564 temp3[len-1] = '\0';
02565 return temp3;
02566 }
02567
02568
02569
02570
02571
02572
02573 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
02574 {
02575 int i;
02576
02577 for ( i=0; i<max_len && name[i]; i++ ) {
02578
02579 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
02580 return False;
02581 }
02582 }
02583
02584 return True;
02585 }
02586
02587
02588
02589
02590
02591
02592
02593 size_t ascii_len_n(const char *src, size_t n)
02594 {
02595 size_t len;
02596
02597 len = strnlen(src, n);
02598 if (len+1 <= n) {
02599 len += 1;
02600 }
02601
02602 return len;
02603 }
02604
02605
02606
02607
02608
02609 size_t utf16_len(const void *buf)
02610 {
02611 size_t len;
02612
02613 for (len = 0; SVAL(buf,len); len += 2) ;
02614
02615 return len + 2;
02616 }
02617
02618
02619
02620
02621
02622
02623 size_t utf16_len_n(const void *src, size_t n)
02624 {
02625 size_t len;
02626
02627 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
02628
02629 if (len+2 <= n) {
02630 len += 2;
02631 }
02632
02633 return len;
02634 }
02635
02636
02637
02638
02639
02640
02641 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
02642 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
02643
02644 char *escape_shell_string(const char *src)
02645 {
02646 size_t srclen = strlen(src);
02647 char *ret = SMB_MALLOC((srclen * 2) + 1);
02648 char *dest = ret;
02649 BOOL in_s_quote = False;
02650 BOOL in_d_quote = False;
02651 BOOL next_escaped = False;
02652
02653 if (!ret) {
02654 return NULL;
02655 }
02656
02657 while (*src) {
02658 size_t c_size;
02659 codepoint_t c = next_codepoint(src, &c_size);
02660
02661 if (c == INVALID_CODEPOINT) {
02662 SAFE_FREE(ret);
02663 return NULL;
02664 }
02665
02666 if (c_size > 1) {
02667 memcpy(dest, src, c_size);
02668 src += c_size;
02669 dest += c_size;
02670 next_escaped = False;
02671 continue;
02672 }
02673
02674
02675
02676
02677
02678
02679 if (next_escaped) {
02680 *dest++ = *src++;
02681 next_escaped = False;
02682 continue;
02683 }
02684
02685
02686
02687
02688
02689
02690
02691 if (in_s_quote) {
02692 if (*src == '\'') {
02693 in_s_quote = False;
02694 }
02695 *dest++ = *src++;
02696 continue;
02697 }
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708 if (in_d_quote) {
02709 if (*src == '\\') {
02710
02711
02712
02713
02714
02715
02716
02717 char nextchar;
02718
02719 c = next_codepoint(&src[1], &c_size);
02720 if (c == INVALID_CODEPOINT) {
02721 SAFE_FREE(ret);
02722 return NULL;
02723 }
02724 if (c_size > 1) {
02725
02726
02727
02728
02729 *dest++ = *src++;
02730 continue;
02731 }
02732
02733 nextchar = src[1];
02734
02735 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
02736 next_escaped = True;
02737 }
02738 *dest++ = *src++;
02739 continue;
02740 }
02741
02742 if (*src == '\"') {
02743
02744 in_d_quote = False;
02745 *dest++ = *src++;
02746 continue;
02747 }
02748
02749
02750
02751
02752
02753
02754
02755 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
02756 *dest++ = '\\';
02757 }
02758 *dest++ = *src++;
02759 continue;
02760 }
02761
02762
02763
02764
02765
02766
02767 if (*src == '\\') {
02768
02769 next_escaped = True;
02770 *dest++ = *src++;
02771 continue;
02772 }
02773
02774 if (*src == '\'') {
02775
02776 in_s_quote = True;
02777 *dest++ = *src++;
02778 continue;
02779 }
02780
02781 if (*src == '\"') {
02782
02783 in_d_quote = True;
02784 *dest++ = *src++;
02785 continue;
02786 }
02787
02788
02789
02790 if (!strchr(INCLUDE_LIST, (int)*src)) {
02791 *dest++ = '\\';
02792 }
02793 *dest++ = *src++;
02794 }
02795 *dest++ = '\0';
02796 return ret;
02797 }