util_str.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. /*
  2. Unix SMB/Netbios implementation.
  3. Version 1.9.
  4. Samba utility functions
  5. Copyright (C) Andrew Tridgell 1992-1998
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. */
  18. #include "includes.h"
  19. extern int DEBUGLEVEL;
  20. static char *last_ptr=NULL;
  21. void set_first_token(char *ptr)
  22. {
  23. last_ptr = ptr;
  24. }
  25. /****************************************************************************
  26. Get the next token from a string, return False if none found
  27. handles double-quotes.
  28. Based on a routine by GJC@VILLAGE.COM.
  29. Extensively modified by Andrew.Tridgell@anu.edu.au
  30. ****************************************************************************/
  31. BOOL next_token(char **ptr,char *buff, const char *sep, size_t bufsize)
  32. {
  33. char *s;
  34. BOOL quoted;
  35. size_t len=1;
  36. if (!ptr) ptr = &last_ptr;
  37. if (!ptr) return(False);
  38. s = *ptr;
  39. /* default to simple separators */
  40. if (!sep) sep = " \t\n\r";
  41. /* find the first non sep char */
  42. while(*s && strchr(sep,*s)) s++;
  43. /* nothing left? */
  44. if (! *s) return(False);
  45. /* copy over the token */
  46. for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
  47. {
  48. if (*s == '\"') {
  49. quoted = !quoted;
  50. } else {
  51. len++;
  52. *buff++ = *s;
  53. }
  54. }
  55. *ptr = (*s) ? s+1 : s;
  56. *buff = 0;
  57. last_ptr = *ptr;
  58. return(True);
  59. }
  60. #if 0
  61. /****************************************************************************
  62. Convert list of tokens to array; dependent on above routine.
  63. Uses last_ptr from above - bit of a hack.
  64. ****************************************************************************/
  65. char **toktocliplist(int *ctok, char *sep)
  66. {
  67. char *s=last_ptr;
  68. int ictok=0;
  69. char **ret, **iret;
  70. if (!sep) sep = " \t\n\r";
  71. while(*s && strchr(sep,*s)) s++;
  72. /* nothing left? */
  73. if (!*s) return(NULL);
  74. do {
  75. ictok++;
  76. while(*s && (!strchr(sep,*s))) s++;
  77. while(*s && strchr(sep,*s)) *s++=0;
  78. } while(*s);
  79. *ctok=ictok;
  80. s=last_ptr;
  81. if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
  82. while(ictok--) {
  83. *iret++=s;
  84. while(*s++);
  85. while(!*s) s++;
  86. }
  87. return ret;
  88. }
  89. #endif /*0 */
  90. /*******************************************************************
  91. case insensitive string compararison
  92. ********************************************************************/
  93. int StrCaseCmp(const char *s, const char *t)
  94. {
  95. /* compare until we run out of string, either t or s, or find a difference */
  96. /* We *must* use toupper rather than tolower here due to the
  97. asynchronous upper to lower mapping.
  98. */
  99. #if !defined(KANJI_WIN95_COMPATIBILITY)
  100. /*
  101. * For completeness we should put in equivalent code for code pages
  102. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  103. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  104. * here. They both treat full width ascii characters as case senstive
  105. * filenames (ie. they don't do the work we do here).
  106. * JRA.
  107. */
  108. if(lp_client_code_page() == KANJI_CODEPAGE)
  109. {
  110. /* Win95 treats full width ascii characters as case sensitive. */
  111. int diff;
  112. for (;;)
  113. {
  114. if (!*s || !*t)
  115. return toupper (*s) - toupper (*t);
  116. else if (is_sj_alph (*s) && is_sj_alph (*t))
  117. {
  118. diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
  119. if (diff)
  120. return diff;
  121. s += 2;
  122. t += 2;
  123. }
  124. else if (is_shift_jis (*s) && is_shift_jis (*t))
  125. {
  126. diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
  127. if (diff)
  128. return diff;
  129. diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
  130. if (diff)
  131. return diff;
  132. s += 2;
  133. t += 2;
  134. }
  135. else if (is_shift_jis (*s))
  136. return 1;
  137. else if (is_shift_jis (*t))
  138. return -1;
  139. else
  140. {
  141. diff = toupper (*s) - toupper (*t);
  142. if (diff)
  143. return diff;
  144. s++;
  145. t++;
  146. }
  147. }
  148. }
  149. else
  150. #endif /* KANJI_WIN95_COMPATIBILITY */
  151. {
  152. while (*s && *t && toupper(*s) == toupper(*t))
  153. {
  154. s++;
  155. t++;
  156. }
  157. return(toupper(*s) - toupper(*t));
  158. }
  159. }
  160. /*******************************************************************
  161. case insensitive string compararison, length limited
  162. ********************************************************************/
  163. int StrnCaseCmp(const char *s, const char *t, size_t n)
  164. {
  165. /* compare until we run out of string, either t or s, or chars */
  166. /* We *must* use toupper rather than tolower here due to the
  167. asynchronous upper to lower mapping.
  168. */
  169. #if !defined(KANJI_WIN95_COMPATIBILITY)
  170. /*
  171. * For completeness we should put in equivalent code for code pages
  172. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  173. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  174. * here. They both treat full width ascii characters as case senstive
  175. * filenames (ie. they don't do the work we do here).
  176. * JRA.
  177. */
  178. if(lp_client_code_page() == KANJI_CODEPAGE)
  179. {
  180. /* Win95 treats full width ascii characters as case sensitive. */
  181. int diff;
  182. for (;n > 0;)
  183. {
  184. if (!*s || !*t)
  185. return toupper (*s) - toupper (*t);
  186. else if (is_sj_alph (*s) && is_sj_alph (*t))
  187. {
  188. diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
  189. if (diff)
  190. return diff;
  191. s += 2;
  192. t += 2;
  193. n -= 2;
  194. }
  195. else if (is_shift_jis (*s) && is_shift_jis (*t))
  196. {
  197. diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
  198. if (diff)
  199. return diff;
  200. diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
  201. if (diff)
  202. return diff;
  203. s += 2;
  204. t += 2;
  205. n -= 2;
  206. }
  207. else if (is_shift_jis (*s))
  208. return 1;
  209. else if (is_shift_jis (*t))
  210. return -1;
  211. else
  212. {
  213. diff = toupper (*s) - toupper (*t);
  214. if (diff)
  215. return diff;
  216. s++;
  217. t++;
  218. n--;
  219. }
  220. }
  221. return 0;
  222. }
  223. else
  224. #endif /* KANJI_WIN95_COMPATIBILITY */
  225. {
  226. while (n && *s && *t && toupper(*s) == toupper(*t))
  227. {
  228. s++;
  229. t++;
  230. n--;
  231. }
  232. /* not run out of chars - strings are different lengths */
  233. if (n)
  234. return(toupper(*s) - toupper(*t));
  235. /* identical up to where we run out of chars,
  236. and strings are same length */
  237. return(0);
  238. }
  239. }
  240. /*******************************************************************
  241. compare 2 strings
  242. ********************************************************************/
  243. BOOL strequal(const char *s1, const char *s2)
  244. {
  245. if (s1 == s2) return(True);
  246. if (!s1 || !s2) return(False);
  247. return(StrCaseCmp(s1,s2)==0);
  248. }
  249. /*******************************************************************
  250. compare 2 strings up to and including the nth char.
  251. ******************************************************************/
  252. BOOL strnequal(const char *s1,const char *s2,size_t n)
  253. {
  254. if (s1 == s2) return(True);
  255. if (!s1 || !s2 || !n) return(False);
  256. return(StrnCaseCmp(s1,s2,n)==0);
  257. }
  258. /*******************************************************************
  259. compare 2 strings (case sensitive)
  260. ********************************************************************/
  261. BOOL strcsequal(const char *s1,const char *s2)
  262. {
  263. if (s1 == s2) return(True);
  264. if (!s1 || !s2) return(False);
  265. return(strcmp(s1,s2)==0);
  266. }
  267. /*******************************************************************
  268. convert a string to lower case
  269. ********************************************************************/
  270. void strlower(char *s)
  271. {
  272. while (*s)
  273. {
  274. #if !defined(KANJI_WIN95_COMPATIBILITY)
  275. /*
  276. * For completeness we should put in equivalent code for code pages
  277. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  278. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  279. * here. They both treat full width ascii characters as case senstive
  280. * filenames (ie. they don't do the work we do here).
  281. * JRA.
  282. */
  283. if(lp_client_code_page() == KANJI_CODEPAGE)
  284. {
  285. /* Win95 treats full width ascii characters as case sensitive. */
  286. if (is_shift_jis (*s))
  287. {
  288. if (is_sj_upper (s[0], s[1]))
  289. s[1] = sj_tolower2 (s[1]);
  290. s += 2;
  291. }
  292. else if (is_kana (*s))
  293. {
  294. s++;
  295. }
  296. else
  297. {
  298. if (isupper(*s))
  299. *s = tolower(*s);
  300. s++;
  301. }
  302. }
  303. else
  304. #endif /* KANJI_WIN95_COMPATIBILITY */
  305. {
  306. size_t skip = skip_multibyte_char( *s );
  307. if( skip != 0 )
  308. s += skip;
  309. else
  310. {
  311. if (isupper(*s))
  312. *s = tolower(*s);
  313. s++;
  314. }
  315. }
  316. }
  317. }
  318. /*******************************************************************
  319. convert a string to upper case
  320. ********************************************************************/
  321. void strupper(char *s)
  322. {
  323. while (*s)
  324. {
  325. #if !defined(KANJI_WIN95_COMPATIBILITY)
  326. /*
  327. * For completeness we should put in equivalent code for code pages
  328. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  329. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  330. * here. They both treat full width ascii characters as case senstive
  331. * filenames (ie. they don't do the work we do here).
  332. * JRA.
  333. */
  334. if(lp_client_code_page() == KANJI_CODEPAGE)
  335. {
  336. /* Win95 treats full width ascii characters as case sensitive. */
  337. if (is_shift_jis (*s))
  338. {
  339. if (is_sj_lower (s[0], s[1]))
  340. s[1] = sj_toupper2 (s[1]);
  341. s += 2;
  342. }
  343. else if (is_kana (*s))
  344. {
  345. s++;
  346. }
  347. else
  348. {
  349. if (islower(*s))
  350. *s = toupper(*s);
  351. s++;
  352. }
  353. }
  354. else
  355. #endif /* KANJI_WIN95_COMPATIBILITY */
  356. {
  357. size_t skip = skip_multibyte_char( *s );
  358. if( skip != 0 )
  359. s += skip;
  360. else
  361. {
  362. if (islower(*s))
  363. *s = toupper(*s);
  364. s++;
  365. }
  366. }
  367. }
  368. }
  369. #if 0
  370. /*******************************************************************
  371. convert a string to "normal" form
  372. ********************************************************************/
  373. void strnorm(char *s)
  374. {
  375. extern int case_default;
  376. if (case_default == CASE_UPPER)
  377. strupper(s);
  378. else
  379. strlower(s);
  380. }
  381. /*******************************************************************
  382. check if a string is in "normal" case
  383. ********************************************************************/
  384. BOOL strisnormal(char *s)
  385. {
  386. extern int case_default;
  387. if (case_default == CASE_UPPER)
  388. return(!strhaslower(s));
  389. return(!strhasupper(s));
  390. }
  391. #endif /* 0 */
  392. /****************************************************************************
  393. string replace
  394. ****************************************************************************/
  395. void string_replace(char *s,char oldc,char newc)
  396. {
  397. size_t skip;
  398. while (*s)
  399. {
  400. skip = skip_multibyte_char( *s );
  401. if( skip != 0 )
  402. s += skip;
  403. else
  404. {
  405. if (oldc == *s)
  406. *s = newc;
  407. s++;
  408. }
  409. }
  410. }
  411. /*******************************************************************
  412. skip past some strings in a buffer
  413. ********************************************************************/
  414. char *skip_string(char *buf,size_t n)
  415. {
  416. while (n--)
  417. buf += strlen(buf) + 1;
  418. return(buf);
  419. }
  420. /*******************************************************************
  421. Count the number of characters in a string. Normally this will
  422. be the same as the number of bytes in a string for single byte strings,
  423. but will be different for multibyte.
  424. 16.oct.98, jdblair@cobaltnet.com.
  425. ********************************************************************/
  426. size_t str_charnum(const char *s)
  427. {
  428. size_t len = 0;
  429. while (*s != '\0') {
  430. int skip = skip_multibyte_char(*s);
  431. s += (skip ? skip : 1);
  432. len++;
  433. }
  434. return len;
  435. }
  436. /*******************************************************************
  437. trim the specified elements off the front and back of a string
  438. ********************************************************************/
  439. BOOL trim_string(char *s,const char *front,const char *back)
  440. {
  441. BOOL ret = False;
  442. size_t front_len = (front && *front) ? strlen(front) : 0;
  443. size_t back_len = (back && *back) ? strlen(back) : 0;
  444. size_t s_len;
  445. while (front_len && strncmp(s, front, front_len) == 0)
  446. {
  447. char *p = s;
  448. ret = True;
  449. while (1)
  450. {
  451. if (!(*p = p[front_len]))
  452. break;
  453. p++;
  454. }
  455. }
  456. /*
  457. * We split out the multibyte code page
  458. * case here for speed purposes. Under a
  459. * multibyte code page we need to walk the
  460. * string forwards only and multiple times.
  461. * Thanks to John Blair for finding this
  462. * one. JRA.
  463. */
  464. if(back_len)
  465. {
  466. if(!is_multibyte_codepage())
  467. {
  468. s_len = strlen(s);
  469. while ((s_len >= back_len) &&
  470. (strncmp(s + s_len - back_len, back, back_len)==0))
  471. {
  472. ret = True;
  473. s[s_len - back_len] = '\0';
  474. s_len = strlen(s);
  475. }
  476. }
  477. else
  478. {
  479. /*
  480. * Multibyte code page case.
  481. * Keep going through the string, trying
  482. * to match the 'back' string with the end
  483. * of the string. If we get a match, truncate
  484. * 'back' off the end of the string and
  485. * go through the string again from the
  486. * start. Keep doing this until we have
  487. * gone through the string with no match
  488. * at the string end.
  489. */
  490. size_t mb_back_len = str_charnum(back);
  491. size_t mb_s_len = str_charnum(s);
  492. while(mb_s_len >= mb_back_len)
  493. {
  494. size_t charcount = 0;
  495. char *mbp = s;
  496. while(charcount < (mb_s_len - mb_back_len))
  497. {
  498. size_t skip = skip_multibyte_char(*mbp);
  499. mbp += (skip ? skip : 1);
  500. charcount++;
  501. }
  502. /*
  503. * mbp now points at mb_back_len multibyte
  504. * characters from the end of s.
  505. */
  506. if(strcmp(mbp, back) == 0)
  507. {
  508. ret = True;
  509. *mbp = '\0';
  510. mb_s_len = str_charnum(s);
  511. mbp = s;
  512. }
  513. else
  514. break;
  515. } /* end while mb_s_len... */
  516. } /* end else .. */
  517. } /* end if back_len .. */
  518. return(ret);
  519. }
  520. #if 0
  521. /****************************************************************************
  522. does a string have any uppercase chars in it?
  523. ****************************************************************************/
  524. BOOL strhasupper(const char *s)
  525. {
  526. while (*s)
  527. {
  528. #if !defined(KANJI_WIN95_COMPATIBILITY)
  529. /*
  530. * For completeness we should put in equivalent code for code pages
  531. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  532. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  533. * here. They both treat full width ascii characters as case senstive
  534. * filenames (ie. they don't do the work we do here).
  535. * JRA.
  536. */
  537. if(lp_client_code_page() == KANJI_CODEPAGE)
  538. {
  539. /* Win95 treats full width ascii characters as case sensitive. */
  540. if (is_shift_jis (*s))
  541. s += 2;
  542. else if (is_kana (*s))
  543. s++;
  544. else
  545. {
  546. if (isupper(*s))
  547. return(True);
  548. s++;
  549. }
  550. }
  551. else
  552. #endif /* KANJI_WIN95_COMPATIBILITY */
  553. {
  554. size_t skip = skip_multibyte_char( *s );
  555. if( skip != 0 )
  556. s += skip;
  557. else {
  558. if (isupper(*s))
  559. return(True);
  560. s++;
  561. }
  562. }
  563. }
  564. return(False);
  565. }
  566. /****************************************************************************
  567. does a string have any lowercase chars in it?
  568. ****************************************************************************/
  569. BOOL strhaslower(const char *s)
  570. {
  571. while (*s)
  572. {
  573. #if !defined(KANJI_WIN95_COMPATIBILITY)
  574. /*
  575. * For completeness we should put in equivalent code for code pages
  576. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  577. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  578. * here. They both treat full width ascii characters as case senstive
  579. * filenames (ie. they don't do the work we do here).
  580. * JRA.
  581. */
  582. if(lp_client_code_page() == KANJI_CODEPAGE)
  583. {
  584. /* Win95 treats full width ascii characters as case sensitive. */
  585. if (is_shift_jis (*s))
  586. {
  587. if (is_sj_upper (s[0], s[1]))
  588. return(True);
  589. if (is_sj_lower (s[0], s[1]))
  590. return (True);
  591. s += 2;
  592. }
  593. else if (is_kana (*s))
  594. {
  595. s++;
  596. }
  597. else
  598. {
  599. if (islower(*s))
  600. return(True);
  601. s++;
  602. }
  603. }
  604. else
  605. #endif /* KANJI_WIN95_COMPATIBILITY */
  606. {
  607. size_t skip = skip_multibyte_char( *s );
  608. if( skip != 0 )
  609. s += skip;
  610. else {
  611. if (islower(*s))
  612. return(True);
  613. s++;
  614. }
  615. }
  616. }
  617. return(False);
  618. }
  619. #endif /*0 */
  620. /****************************************************************************
  621. find the number of chars in a string
  622. ****************************************************************************/
  623. size_t count_chars(const char *s,char c)
  624. {
  625. size_t count=0;
  626. #if !defined(KANJI_WIN95_COMPATIBILITY)
  627. /*
  628. * For completeness we should put in equivalent code for code pages
  629. * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
  630. * doubt anyone wants Samba to behave differently from Win95 and WinNT
  631. * here. They both treat full width ascii characters as case senstive
  632. * filenames (ie. they don't do the work we do here).
  633. * JRA.
  634. */
  635. if(lp_client_code_page() == KANJI_CODEPAGE)
  636. {
  637. /* Win95 treats full width ascii characters as case sensitive. */
  638. while (*s)
  639. {
  640. if (is_shift_jis (*s))
  641. s += 2;
  642. else
  643. {
  644. if (*s == c)
  645. count++;
  646. s++;
  647. }
  648. }
  649. }
  650. else
  651. #endif /* KANJI_WIN95_COMPATIBILITY */
  652. {
  653. while (*s)
  654. {
  655. size_t skip = skip_multibyte_char( *s );
  656. if( skip != 0 )
  657. s += skip;
  658. else {
  659. if (*s == c)
  660. count++;
  661. s++;
  662. }
  663. }
  664. }
  665. return(count);
  666. }
  667. /*******************************************************************
  668. safe string copy into a known length string. maxlength does not
  669. include the terminating zero.
  670. ********************************************************************/
  671. char *safe_strcpy(char *dest,const char *src, size_t maxlength)
  672. {
  673. size_t len;
  674. if (!dest) {
  675. DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
  676. return NULL;
  677. }
  678. if (!src) {
  679. *dest = 0;
  680. return dest;
  681. }
  682. len = strlen(src);
  683. if (len > maxlength) {
  684. DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
  685. (int)(len-maxlength), src));
  686. len = maxlength;
  687. }
  688. memcpy(dest, src, len);
  689. dest[len] = 0;
  690. return dest;
  691. }
  692. /*******************************************************************
  693. safe string cat into a string. maxlength does not
  694. include the terminating zero.
  695. ********************************************************************/
  696. char *safe_strcat(char *dest, const char *src, size_t maxlength)
  697. {
  698. size_t src_len, dest_len;
  699. if (!dest) {
  700. DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
  701. return NULL;
  702. }
  703. if (!src) {
  704. return dest;
  705. }
  706. src_len = strlen(src);
  707. dest_len = strlen(dest);
  708. if (src_len + dest_len > maxlength) {
  709. DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
  710. (int)(src_len + dest_len - maxlength), src));
  711. src_len = maxlength - dest_len;
  712. }
  713. memcpy(&dest[dest_len], src, src_len);
  714. dest[dest_len + src_len] = 0;
  715. return dest;
  716. }
  717. /****************************************************************************
  718. this is a safer strcpy(), meant to prevent core dumps when nasty things happen
  719. ****************************************************************************/
  720. char *StrCpy(char *dest,const char *src)
  721. {
  722. char *d = dest;
  723. /* I don't want to get lazy with these ... */
  724. SMB_ASSERT(dest && src);
  725. if (!dest) return(NULL);
  726. if (!src) {
  727. *dest = 0;
  728. return(dest);
  729. }
  730. while ((*d++ = *src++)) ;
  731. return(dest);
  732. }
  733. /****************************************************************************
  734. like strncpy but always null terminates. Make sure there is room!
  735. ****************************************************************************/
  736. char *StrnCpy(char *dest,const char *src,size_t n)
  737. {
  738. char *d = dest;
  739. if (!dest) return(NULL);
  740. if (!src) {
  741. *dest = 0;
  742. return(dest);
  743. }
  744. while (n-- && (*d++ = *src++)) ;
  745. *d = 0;
  746. return(dest);
  747. }
  748. #if 0
  749. /****************************************************************************
  750. like strncpy but copies up to the character marker. always null terminates.
  751. returns a pointer to the character marker in the source string (src).
  752. ****************************************************************************/
  753. char *strncpyn(char *dest, const char *src,size_t n, char c)
  754. {
  755. char *p;
  756. size_t str_len;
  757. p = strchr(src, c);
  758. if (p == NULL)
  759. {
  760. DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
  761. return NULL;
  762. }
  763. str_len = PTR_DIFF(p, src);
  764. strncpy(dest, src, MIN(n, str_len));
  765. dest[str_len] = '\0';
  766. return p;
  767. }
  768. /*************************************************************
  769. Routine to get hex characters and turn them into a 16 byte array.
  770. the array can be variable length, and any non-hex-numeric
  771. characters are skipped. "0xnn" or "0Xnn" is specially catered
  772. for.
  773. valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
  774. **************************************************************/
  775. size_t strhex_to_str(char *p, size_t len, const char *strhex)
  776. {
  777. size_t i;
  778. size_t num_chars = 0;
  779. unsigned char lonybble, hinybble;
  780. char *hexchars = "0123456789ABCDEF";
  781. char *p1 = NULL, *p2 = NULL;
  782. for (i = 0; i < len && strhex[i] != 0; i++)
  783. {
  784. if (strnequal(hexchars, "0x", 2))
  785. {
  786. i++; /* skip two chars */
  787. continue;
  788. }
  789. if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
  790. {
  791. break;
  792. }
  793. i++; /* next hex digit */
  794. if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
  795. {
  796. break;
  797. }
  798. /* get the two nybbles */
  799. hinybble = PTR_DIFF(p1, hexchars);
  800. lonybble = PTR_DIFF(p2, hexchars);
  801. p[num_chars] = (hinybble << 4) | lonybble;
  802. num_chars++;
  803. p1 = NULL;
  804. p2 = NULL;
  805. }
  806. return num_chars;
  807. }
  808. /****************************************************************************
  809. check if a string is part of a list
  810. ****************************************************************************/
  811. BOOL in_list(char *s,char *list,BOOL casesensitive)
  812. {
  813. pstring tok;
  814. char *p=list;
  815. if (!list) return(False);
  816. while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
  817. if (casesensitive) {
  818. if (strcmp(tok,s) == 0)
  819. return(True);
  820. } else {
  821. if (StrCaseCmp(tok,s) == 0)
  822. return(True);
  823. }
  824. }
  825. return(False);
  826. }
  827. #endif /*0 */
  828. /* this is used to prevent lots of mallocs of size 1 */
  829. static char *null_string = NULL;
  830. /****************************************************************************
  831. set a string value, allocing the space for the string
  832. ****************************************************************************/
  833. BOOL string_init(char **dest,const char *src)
  834. {
  835. size_t l;
  836. if (!src)
  837. src = "";
  838. l = strlen(src);
  839. if (l == 0)
  840. {
  841. if (!null_string) {
  842. if((null_string = (char *)malloc(1)) == NULL) {
  843. DEBUG(0,("string_init: malloc fail for null_string.\n"));
  844. return False;
  845. }
  846. *null_string = 0;
  847. }
  848. *dest = null_string;
  849. }
  850. else
  851. {
  852. (*dest) = (char *)malloc(l+1);
  853. if ((*dest) == NULL) {
  854. DEBUG(0,("Out of memory in string_init\n"));
  855. return False;
  856. }
  857. pstrcpy(*dest,src);
  858. }
  859. return(True);
  860. }
  861. /****************************************************************************
  862. free a string value
  863. ****************************************************************************/
  864. void string_free(char **s)
  865. {
  866. if (!s || !(*s)) return;
  867. if (*s == null_string)
  868. *s = NULL;
  869. if (*s) free(*s);
  870. *s = NULL;
  871. }
  872. /****************************************************************************
  873. set a string value, allocing the space for the string, and deallocating any
  874. existing space
  875. ****************************************************************************/
  876. BOOL string_set(char **dest,const char *src)
  877. {
  878. string_free(dest);
  879. return(string_init(dest,src));
  880. }
  881. /****************************************************************************
  882. substitute a string for a pattern in another string. Make sure there is
  883. enough room!
  884. This routine looks for pattern in s and replaces it with
  885. insert. It may do multiple replacements.
  886. any of " ; ' or ` in the insert string are replaced with _
  887. ****************************************************************************/
  888. void string_sub(char *s,const char *pattern,const char *insert)
  889. {
  890. char *p;
  891. size_t ls,lp,li, i;
  892. if (!insert || !pattern || !s) return;
  893. ls = strlen(s);
  894. lp = strlen(pattern);
  895. li = strlen(insert);
  896. if (!*pattern) return;
  897. while (lp <= ls && (p = strstr(s,pattern))) {
  898. memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
  899. for (i=0;i<li;i++) {
  900. switch (insert[i]) {
  901. case '`':
  902. case '"':
  903. case '\'':
  904. case ';':
  905. p[i] = '_';
  906. break;
  907. default:
  908. p[i] = insert[i];
  909. }
  910. }
  911. s = p + li;
  912. ls += (li-lp);
  913. }
  914. }
  915. #if 0
  916. /****************************************************************************
  917. similar to string_sub() but allows for any character to be substituted.
  918. Use with caution!
  919. ****************************************************************************/
  920. void all_string_sub(char *s,const char *pattern,const char *insert)
  921. {
  922. char *p;
  923. size_t ls,lp,li;
  924. if (!insert || !pattern || !s) return;
  925. ls = strlen(s);
  926. lp = strlen(pattern);
  927. li = strlen(insert);
  928. if (!*pattern) return;
  929. while (lp <= ls && (p = strstr(s,pattern))) {
  930. memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
  931. memcpy(p, insert, li);
  932. s = p + li;
  933. ls += (li-lp);
  934. }
  935. }
  936. /****************************************************************************
  937. splits out the front and back at a separator.
  938. ****************************************************************************/
  939. void split_at_last_component(char *path, char *front, char sep, char *back)
  940. {
  941. char *p = strrchr(path, sep);
  942. if (p != NULL)
  943. {
  944. *p = 0;
  945. }
  946. if (front != NULL)
  947. {
  948. pstrcpy(front, path);
  949. }
  950. if (p != NULL)
  951. {
  952. if (back != NULL)
  953. {
  954. pstrcpy(back, p+1);
  955. }
  956. *p = '\\';
  957. }
  958. else
  959. {
  960. if (back != NULL)
  961. {
  962. back[0] = 0;
  963. }
  964. }
  965. }
  966. #endif /*0 */