miscutil.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. /*********************************************************************
  2. *
  3. * File : $Source: /cvsroot/ijbswa/current/miscutil.c,v $
  4. *
  5. * Purpose : zalloc, hash_string, strcmpic, strncmpic, and
  6. * MinGW32 strdup functions. These are each too small
  7. * to deserve their own file but don't really fit in
  8. * any other file.
  9. *
  10. * Copyright : Written by and Copyright (C) 2001-2020 the
  11. * Privoxy team. https://www.privoxy.org/
  12. *
  13. * Based on the Internet Junkbuster originally written
  14. * by and Copyright (C) 1997 Anonymous Coders and
  15. * Junkbusters Corporation. http://www.junkbusters.com
  16. *
  17. * The timegm replacement function was taken from GnuPG,
  18. * Copyright (C) 2004 Free Software Foundation, Inc.
  19. *
  20. * This program is free software; you can redistribute it
  21. * and/or modify it under the terms of the GNU General
  22. * Public License as published by the Free Software
  23. * Foundation; either version 2 of the License, or (at
  24. * your option) any later version.
  25. *
  26. * This program is distributed in the hope that it will
  27. * be useful, but WITHOUT ANY WARRANTY; without even the
  28. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  29. * PARTICULAR PURPOSE. See the GNU General Public
  30. * License for more details.
  31. *
  32. * The GNU General Public License should be included with
  33. * this file. If not, you can view it at
  34. * http://www.gnu.org/copyleft/gpl.html
  35. * or write to the Free Software Foundation, Inc., 59
  36. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  37. *
  38. *********************************************************************/
  39. #include "config.h"
  40. #include <stdio.h>
  41. #include <sys/types.h>
  42. #include <stdlib.h>
  43. #if !defined(_WIN32)
  44. #include <unistd.h>
  45. #endif /* #if !defined(_WIN32) */
  46. #include <string.h>
  47. #include <ctype.h>
  48. #include <assert.h>
  49. #if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
  50. #include <time.h>
  51. #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
  52. #include "project.h"
  53. #include "miscutil.h"
  54. #include "jcc.h"
  55. #include "errlog.h"
  56. /*********************************************************************
  57. *
  58. * Function : zalloc
  59. *
  60. * Description : Returns allocated memory that is initialized
  61. * with zeros.
  62. *
  63. * Parameters :
  64. * 1 : size = Size of memory chunk to return.
  65. *
  66. * Returns : Pointer to newly alloc'd memory chunk.
  67. *
  68. *********************************************************************/
  69. void *zalloc(size_t size)
  70. {
  71. void * ret;
  72. #ifdef HAVE_CALLOC
  73. ret = calloc(1, size);
  74. #else
  75. #warning calloc appears to be unavailable. Your platform will become unsupported in the future
  76. if ((ret = (void *)malloc(size)) != NULL)
  77. {
  78. memset(ret, 0, size);
  79. }
  80. #endif
  81. return(ret);
  82. }
  83. /*********************************************************************
  84. *
  85. * Function : zalloc_or_die
  86. *
  87. * Description : zalloc wrapper that either succeeds or causes
  88. * program termination.
  89. *
  90. * Useful in situations were the string length is
  91. * "small" and zalloc() failures couldn't be handled
  92. * better anyway. In case of debug builds, failures
  93. * trigger an assert().
  94. *
  95. * Parameters :
  96. * 1 : size = Size of memory chunk to return.
  97. *
  98. * Returns : Pointer to newly malloc'd memory chunk.
  99. *
  100. *********************************************************************/
  101. void *zalloc_or_die(size_t size)
  102. {
  103. void *buffer;
  104. buffer = zalloc(size);
  105. if (buffer == NULL)
  106. {
  107. assert(buffer != NULL);
  108. log_error(LOG_LEVEL_FATAL, "Out of memory in zalloc_or_die().");
  109. exit(1);
  110. }
  111. return(buffer);
  112. }
  113. /*********************************************************************
  114. *
  115. * Function : strdup_or_die
  116. *
  117. * Description : strdup wrapper that either succeeds or causes
  118. * program termination.
  119. *
  120. * Useful in situations were the string length is
  121. * "small" and strdup() failures couldn't be handled
  122. * better anyway. In case of debug builds, failures
  123. * trigger an assert().
  124. *
  125. * Parameters :
  126. * 1 : str = String to duplicate
  127. *
  128. * Returns : Pointer to newly strdup'd copy of the string.
  129. *
  130. *********************************************************************/
  131. char *strdup_or_die(const char *str)
  132. {
  133. char *new_str;
  134. new_str = strdup(str);
  135. if (new_str == NULL)
  136. {
  137. assert(new_str != NULL);
  138. log_error(LOG_LEVEL_FATAL, "Out of memory in strdup_or_die().");
  139. exit(1);
  140. }
  141. return(new_str);
  142. }
  143. /*********************************************************************
  144. *
  145. * Function : malloc_or_die
  146. *
  147. * Description : malloc wrapper that either succeeds or causes
  148. * program termination.
  149. *
  150. * Useful in situations were the buffer size is "small"
  151. * and malloc() failures couldn't be handled better
  152. * anyway. In case of debug builds, failures trigger
  153. * an assert().
  154. *
  155. * Parameters :
  156. * 1 : buffer_size = Size of the space to allocate
  157. *
  158. * Returns : Pointer to newly malloc'd memory
  159. *
  160. *********************************************************************/
  161. void *malloc_or_die(size_t buffer_size)
  162. {
  163. char *new_buf;
  164. if (buffer_size == 0)
  165. {
  166. log_error(LOG_LEVEL_ERROR,
  167. "malloc_or_die() called with buffer size 0");
  168. assert(buffer_size != 0);
  169. buffer_size = 4096;
  170. }
  171. new_buf = malloc(buffer_size);
  172. if (new_buf == NULL)
  173. {
  174. assert(new_buf != NULL);
  175. log_error(LOG_LEVEL_FATAL, "Out of memory in malloc_or_die().");
  176. exit(1);
  177. }
  178. return(new_buf);
  179. }
  180. #if defined(unix)
  181. /*********************************************************************
  182. *
  183. * Function : write_pid_file
  184. *
  185. * Description : Writes a pid file with the pid of the main process.
  186. * Exits if the file can't be opened
  187. *
  188. * Parameters :
  189. * 1 : pid_file = Path of the pid file that gets created.
  190. *
  191. * Returns : N/A
  192. *
  193. *********************************************************************/
  194. void write_pid_file(const char *pid_file)
  195. {
  196. FILE *fp;
  197. if ((fp = fopen(pid_file, "w")) == NULL)
  198. {
  199. log_error(LOG_LEVEL_FATAL, "can't open pid file '%s': %E", pid_file);
  200. }
  201. else
  202. {
  203. fprintf(fp, "%u\n", (unsigned int) getpid());
  204. fclose (fp);
  205. }
  206. return;
  207. }
  208. #endif /* def unix */
  209. /*********************************************************************
  210. *
  211. * Function : hash_string
  212. *
  213. * Description : Take a string and compute a (hopefully) unique numeric
  214. * integer value. This is useful to "switch" a string.
  215. *
  216. * Parameters :
  217. * 1 : s : string to be hashed.
  218. *
  219. * Returns : The string's hash
  220. *
  221. *********************************************************************/
  222. unsigned int hash_string(const char* s)
  223. {
  224. unsigned int h = 0;
  225. for (; *s; ++s)
  226. {
  227. h = 5 * h + (unsigned int)*s;
  228. }
  229. return (h);
  230. }
  231. /*********************************************************************
  232. *
  233. * Function : strcmpic
  234. *
  235. * Description : Case insensitive string comparison
  236. *
  237. * Parameters :
  238. * 1 : s1 = string 1 to compare
  239. * 2 : s2 = string 2 to compare
  240. *
  241. * Returns : 0 if s1==s2, Negative if s1<s2, Positive if s1>s2
  242. *
  243. *********************************************************************/
  244. int strcmpic(const char *s1, const char *s2)
  245. {
  246. if (!s1) s1 = "";
  247. if (!s2) s2 = "";
  248. while (*s1 && *s2)
  249. {
  250. if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2)))
  251. {
  252. break;
  253. }
  254. s1++, s2++;
  255. }
  256. return(privoxy_tolower(*s1) - privoxy_tolower(*s2));
  257. }
  258. /*********************************************************************
  259. *
  260. * Function : strncmpic
  261. *
  262. * Description : Case insensitive string comparison (up to n characters)
  263. *
  264. * Parameters :
  265. * 1 : s1 = string 1 to compare
  266. * 2 : s2 = string 2 to compare
  267. * 3 : n = maximum characters to compare
  268. *
  269. * Returns : 0 if s1==s2, Negative if s1<s2, Positive if s1>s2
  270. *
  271. *********************************************************************/
  272. int strncmpic(const char *s1, const char *s2, size_t n)
  273. {
  274. if (n <= (size_t)0) return(0);
  275. if (!s1) s1 = "";
  276. if (!s2) s2 = "";
  277. while (*s1 && *s2)
  278. {
  279. if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2)))
  280. {
  281. break;
  282. }
  283. if (--n <= (size_t)0) break;
  284. s1++, s2++;
  285. }
  286. return(privoxy_tolower(*s1) - privoxy_tolower(*s2));
  287. }
  288. /*********************************************************************
  289. *
  290. * Function : chomp
  291. *
  292. * Description : In-situ-eliminate all leading and trailing whitespace
  293. * from a string.
  294. *
  295. * Parameters :
  296. * 1 : s : string to be chomped.
  297. *
  298. * Returns : chomped string
  299. *
  300. *********************************************************************/
  301. char *chomp(char *string)
  302. {
  303. char *p, *q, *r;
  304. /*
  305. * strip trailing whitespace
  306. */
  307. p = string + strlen(string);
  308. while (p > string && privoxy_isspace(*(p-1)))
  309. {
  310. p--;
  311. }
  312. *p = '\0';
  313. /*
  314. * find end of leading whitespace
  315. */
  316. q = r = string;
  317. while (*q && privoxy_isspace(*q))
  318. {
  319. q++;
  320. }
  321. /*
  322. * if there was any, move the rest forwards
  323. */
  324. if (q != string)
  325. {
  326. while (q <= p)
  327. {
  328. *r++ = *q++;
  329. }
  330. }
  331. return(string);
  332. }
  333. /*********************************************************************
  334. *
  335. * Function : string_append
  336. *
  337. * Description : Reallocate target_string and append text to it.
  338. * This makes it easier to append to malloc'd strings.
  339. * This is similar to the (removed) strsav(), but
  340. * running out of memory isn't catastrophic.
  341. *
  342. * Programming style:
  343. *
  344. * The following style provides sufficient error
  345. * checking for this routine, with minimal clutter
  346. * in the source code. It is recommended if you
  347. * have many calls to this function:
  348. *
  349. * char * s = strdup(...); // don't check for error
  350. * string_append(&s, ...); // don't check for error
  351. * string_append(&s, ...); // don't check for error
  352. * string_append(&s, ...); // don't check for error
  353. * if (NULL == s) { ... handle error ... }
  354. *
  355. * OR, equivalently:
  356. *
  357. * char * s = strdup(...); // don't check for error
  358. * string_append(&s, ...); // don't check for error
  359. * string_append(&s, ...); // don't check for error
  360. * if (string_append(&s, ...)) {... handle error ...}
  361. *
  362. * Parameters :
  363. * 1 : target_string = Pointer to old text that is to be
  364. * extended. *target_string will be free()d by this
  365. * routine. target_string must be non-NULL.
  366. * If *target_string is NULL, this routine will
  367. * do nothing and return with an error - this allows
  368. * you to make many calls to this routine and only
  369. * check for errors after the last one.
  370. * 2 : text_to_append = Text to be appended to old.
  371. * Must not be NULL.
  372. *
  373. * Returns : JB_ERR_OK on success, and sets *target_string
  374. * to newly malloc'ed appended string. Caller
  375. * must free(*target_string).
  376. * JB_ERR_MEMORY on out-of-memory. (And free()s
  377. * *target_string and sets it to NULL).
  378. * JB_ERR_MEMORY if *target_string is NULL.
  379. *
  380. *********************************************************************/
  381. jb_err string_append(char **target_string, const char *text_to_append)
  382. {
  383. size_t old_len;
  384. char *new_string;
  385. size_t new_size;
  386. assert(target_string);
  387. assert(text_to_append);
  388. if (*target_string == NULL)
  389. {
  390. return JB_ERR_MEMORY;
  391. }
  392. if (*text_to_append == '\0')
  393. {
  394. return JB_ERR_OK;
  395. }
  396. old_len = strlen(*target_string);
  397. new_size = strlen(text_to_append) + old_len + 1;
  398. if (NULL == (new_string = realloc(*target_string, new_size)))
  399. {
  400. free(*target_string);
  401. *target_string = NULL;
  402. return JB_ERR_MEMORY;
  403. }
  404. strlcpy(new_string + old_len, text_to_append, new_size - old_len);
  405. *target_string = new_string;
  406. return JB_ERR_OK;
  407. }
  408. /*********************************************************************
  409. *
  410. * Function : string_join
  411. *
  412. * Description : Join two strings together. Frees BOTH the original
  413. * strings. If either or both input strings are NULL,
  414. * fails as if it had run out of memory.
  415. *
  416. * For comparison, string_append requires that the
  417. * second string is non-NULL, and doesn't free it.
  418. *
  419. * Rationale: Too often, we want to do
  420. * string_append(s, html_encode(s2)). That assert()s
  421. * if s2 is NULL or if html_encode() runs out of memory.
  422. * It also leaks memory. Proper checking is cumbersome.
  423. * The solution: string_join(s, html_encode(s2)) is safe,
  424. * and will free the memory allocated by html_encode().
  425. *
  426. * Parameters :
  427. * 1 : target_string = Pointer to old text that is to be
  428. * extended. *target_string will be free()d by this
  429. * routine. target_string must be non-NULL.
  430. * 2 : text_to_append = Text to be appended to old.
  431. *
  432. * Returns : JB_ERR_OK on success, and sets *target_string
  433. * to newly malloc'ed appended string. Caller
  434. * must free(*target_string).
  435. * JB_ERR_MEMORY on out-of-memory, or if
  436. * *target_string or text_to_append is NULL. (In
  437. * this case, frees *target_string and text_to_append,
  438. * sets *target_string to NULL).
  439. *
  440. *********************************************************************/
  441. jb_err string_join(char **target_string, char *text_to_append)
  442. {
  443. jb_err err;
  444. assert(target_string);
  445. if (text_to_append == NULL)
  446. {
  447. freez(*target_string);
  448. return JB_ERR_MEMORY;
  449. }
  450. err = string_append(target_string, text_to_append);
  451. freez(text_to_append);
  452. return err;
  453. }
  454. /*********************************************************************
  455. *
  456. * Function : string_toupper
  457. *
  458. * Description : Produce a copy of string with all convertible
  459. * characters converted to uppercase.
  460. *
  461. * Parameters :
  462. * 1 : string = string to convert
  463. *
  464. * Returns : Uppercase copy of string if possible,
  465. * NULL on out-of-memory or if string was NULL.
  466. *
  467. *********************************************************************/
  468. char *string_toupper(const char *string)
  469. {
  470. char *result, *p;
  471. const char *q;
  472. if (!string || ((result = (char *) zalloc(strlen(string) + 1)) == NULL))
  473. {
  474. return NULL;
  475. }
  476. q = string;
  477. p = result;
  478. while (*q != '\0')
  479. {
  480. *p++ = (char)toupper((int) *q++);
  481. }
  482. return result;
  483. }
  484. /*********************************************************************
  485. *
  486. * Function : string_tolower
  487. *
  488. * Description : Produce a copy of string with all convertible
  489. * characters converted to lowercase.
  490. *
  491. * Parameters :
  492. * 1 : string = string to convert
  493. *
  494. * Returns : Lowercase copy of string if possible,
  495. * NULL on out-of-memory or if string was NULL.
  496. *
  497. *********************************************************************/
  498. char *string_tolower(const char *string)
  499. {
  500. char *result, *p;
  501. const char *q;
  502. if (!string || ((result = (char *)zalloc(strlen(string) + 1)) == NULL))
  503. {
  504. return NULL;
  505. }
  506. q = string;
  507. p = result;
  508. while (*q != '\0')
  509. {
  510. *p++ = (char)privoxy_tolower(*q++);
  511. }
  512. return result;
  513. }
  514. /*********************************************************************
  515. *
  516. * Function : string_move
  517. *
  518. * Description : memmove wrapper to move the last part of a string
  519. * towards the beginning, overwriting the part in
  520. * the middle. strlcpy() can't be used here as the
  521. * strings overlap.
  522. *
  523. * Parameters :
  524. * 1 : dst = Destination to overwrite
  525. * 2 : src = Source to move.
  526. *
  527. * Returns : N/A
  528. *
  529. *********************************************************************/
  530. void string_move(char *dst, char *src)
  531. {
  532. assert(dst < src);
  533. /* +1 to copy the terminating nul as well. */
  534. memmove(dst, src, strlen(src)+1);
  535. }
  536. /*********************************************************************
  537. *
  538. * Function : bindup
  539. *
  540. * Description : Duplicate the first n characters of a string that may
  541. * contain '\0' characters.
  542. *
  543. * Parameters :
  544. * 1 : string = string to be duplicated
  545. * 2 : len = number of bytes to duplicate
  546. *
  547. * Returns : pointer to copy, or NULL if failure
  548. *
  549. *********************************************************************/
  550. char *bindup(const char *string, size_t len)
  551. {
  552. char *duplicate;
  553. duplicate = (char *)malloc(len);
  554. if (NULL != duplicate)
  555. {
  556. memcpy(duplicate, string, len);
  557. }
  558. return duplicate;
  559. }
  560. /*********************************************************************
  561. *
  562. * Function : make_path
  563. *
  564. * Description : Takes a directory name and a file name, returns
  565. * the complete path. Handles windows/unix differences.
  566. * If the file name is already an absolute path, or if
  567. * the directory name is NULL or empty, it returns
  568. * the filename.
  569. *
  570. * Parameters :
  571. * 1 : dir: Name of directory or NULL for none.
  572. * 2 : file: Name of file. Should not be NULL or empty.
  573. *
  574. * Returns : "dir/file" (Or on windows, "dir\file").
  575. * It allocates the string on the heap. Caller frees.
  576. * Returns NULL in error (i.e. NULL file or out of
  577. * memory)
  578. *
  579. *********************************************************************/
  580. char * make_path(const char * dir, const char * file)
  581. {
  582. if ((file == NULL) || (*file == '\0'))
  583. {
  584. return NULL; /* Error */
  585. }
  586. if ((dir == NULL) || (*dir == '\0') /* No directory specified */
  587. #if defined(_WIN32)
  588. || (*file == '\\') || (file[1] == ':') /* Absolute path (DOS) */
  589. #else /* ifndef _WIN32 */
  590. || (*file == '/') /* Absolute path (U*ix) */
  591. #endif /* ifndef _WIN32 */
  592. )
  593. {
  594. return strdup(file);
  595. }
  596. else
  597. {
  598. char * path;
  599. size_t path_size = strlen(dir) + strlen(file) + 2; /* +2 for trailing (back)slash and \0 */
  600. #if defined(unix)
  601. if (*dir != '/' && basedir && *basedir)
  602. {
  603. /*
  604. * Relative path, so start with the base directory.
  605. */
  606. path_size += strlen(basedir) + 1; /* +1 for the slash */
  607. path = malloc(path_size);
  608. if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
  609. strlcpy(path, basedir, path_size);
  610. strlcat(path, "/", path_size);
  611. strlcat(path, dir, path_size);
  612. }
  613. else
  614. #endif /* defined unix */
  615. {
  616. path = malloc(path_size);
  617. if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
  618. strlcpy(path, dir, path_size);
  619. }
  620. assert(NULL != path);
  621. #if defined(_WIN32)
  622. if (path[strlen(path)-1] != '\\')
  623. {
  624. strlcat(path, "\\", path_size);
  625. }
  626. #else /* ifndef _WIN32 */
  627. if (path[strlen(path)-1] != '/')
  628. {
  629. strlcat(path, "/", path_size);
  630. }
  631. #endif /* ifndef _WIN32 */
  632. strlcat(path, file, path_size);
  633. return path;
  634. }
  635. }
  636. /*********************************************************************
  637. *
  638. * Function : pick_from_range
  639. *
  640. * Description : Pick a positive number out of a given range.
  641. * Should only be used if randomness would be nice,
  642. * but isn't really necessary.
  643. *
  644. * Parameters :
  645. * 1 : range: Highest possible number to pick.
  646. *
  647. * Returns : Picked number.
  648. *
  649. *********************************************************************/
  650. long int pick_from_range(long int range)
  651. {
  652. long int number;
  653. #ifdef _WIN32
  654. static unsigned long seed = 0;
  655. #endif /* def _WIN32 */
  656. assert(range != 0);
  657. assert(range > 0);
  658. if (range <= 0) return 0;
  659. #ifdef HAVE_ARC4RANDOM
  660. number = arc4random() % range + 1;
  661. #elif defined(HAVE_RANDOM)
  662. number = random() % range + 1;
  663. #elif defined(MUTEX_LOCKS_AVAILABLE)
  664. privoxy_mutex_lock(&rand_mutex);
  665. #ifdef _WIN32
  666. if (!seed)
  667. {
  668. seed = (unsigned long)(GetCurrentThreadId()+GetTickCount());
  669. }
  670. srand(seed);
  671. seed = (unsigned long)((rand() << 16) + rand());
  672. #endif /* def _WIN32 */
  673. number = (unsigned long)((rand() << 16) + (rand())) % (unsigned long)(range + 1);
  674. privoxy_mutex_unlock(&rand_mutex);
  675. #else
  676. /*
  677. * XXX: Which platforms reach this and are there
  678. * better options than just using rand() and hoping
  679. * that it's safe?
  680. */
  681. log_error(LOG_LEVEL_INFO, "No thread-safe PRNG available? Header time randomization "
  682. "might cause crashes, predictable results or even combine these fine options.");
  683. number = rand() % (long int)(range + 1);
  684. #endif /* (def HAVE_ARC4RANDOM) */
  685. return number;
  686. }
  687. #ifdef USE_PRIVOXY_STRLCPY
  688. /*********************************************************************
  689. *
  690. * Function : privoxy_strlcpy
  691. *
  692. * Description : strlcpy(3) look-alike for those without decent libc.
  693. *
  694. * Parameters :
  695. * 1 : destination: buffer to copy into.
  696. * 2 : source: String to copy.
  697. * 3 : size: Size of destination buffer.
  698. *
  699. * Returns : The length of the string that privoxy_strlcpy() tried to create.
  700. *
  701. *********************************************************************/
  702. size_t privoxy_strlcpy(char *destination, const char *source, const size_t size)
  703. {
  704. if (0 < size)
  705. {
  706. snprintf(destination, size, "%s", source);
  707. /*
  708. * Platforms that lack strlcpy() also tend to have
  709. * a broken snprintf implementation that doesn't
  710. * guarantee nul termination.
  711. *
  712. * XXX: the configure script should detect and reject those.
  713. */
  714. destination[size-1] = '\0';
  715. }
  716. return strlen(source);
  717. }
  718. #endif /* def USE_PRIVOXY_STRLCPY */
  719. #ifndef HAVE_STRLCAT
  720. /*********************************************************************
  721. *
  722. * Function : privoxy_strlcat
  723. *
  724. * Description : strlcat(3) look-alike for those without decent libc.
  725. *
  726. * Parameters :
  727. * 1 : destination: C string.
  728. * 2 : source: String to copy.
  729. * 3 : size: Size of destination buffer.
  730. *
  731. * Returns : The length of the string that privoxy_strlcat() tried to create.
  732. *
  733. *********************************************************************/
  734. size_t privoxy_strlcat(char *destination, const char *source, const size_t size)
  735. {
  736. const size_t old_length = strlen(destination);
  737. return old_length + strlcpy(destination + old_length, source, size - old_length);
  738. }
  739. #endif /* ndef HAVE_STRLCAT */
  740. /*********************************************************************
  741. *
  742. * Function : privoxy_millisleep
  743. *
  744. * Description : Sleep a number of milliseconds
  745. *
  746. * Parameters :
  747. * 1 : delay: Number of milliseconds to sleep
  748. *
  749. * Returns : -1 on error, 0 otherwise
  750. *
  751. *********************************************************************/
  752. int privoxy_millisleep(unsigned milliseconds)
  753. {
  754. #ifdef HAVE_NANOSLEEP
  755. struct timespec rqtp = {0};
  756. struct timespec rmtp = {0};
  757. rqtp.tv_sec = milliseconds / 1000;
  758. rqtp.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
  759. return nanosleep(&rqtp, &rmtp);
  760. #elif defined (_WIN32)
  761. Sleep(milliseconds);
  762. return 0;
  763. #else
  764. #warning Missing privoxy_milisleep() implementation. delay-response{} will not work.
  765. return -1;
  766. #endif /* def HAVE_NANOSLEEP */
  767. }
  768. /*********************************************************************
  769. *
  770. * Function : privoxy_gmtime_r
  771. *
  772. * Description : Behave like gmtime_r() and convert a
  773. * time_t to a struct tm.
  774. *
  775. * Parameters :
  776. * 1 : time_spec: The time to convert
  777. * 2 : result: The struct tm to use as storage
  778. *
  779. * Returns : Pointer to the result or NULL on error.
  780. *
  781. *********************************************************************/
  782. struct tm *privoxy_gmtime_r(const time_t *time_spec, struct tm *result)
  783. {
  784. struct tm *timeptr;
  785. #ifdef HAVE_GMTIME_R
  786. timeptr = gmtime_r(time_spec, result);
  787. #elif defined(MUTEX_LOCKS_AVAILABLE)
  788. privoxy_mutex_lock(&gmtime_mutex);
  789. timeptr = gmtime(time_spec);
  790. #else
  791. #warning Using unlocked gmtime()
  792. timeptr = gmtime(time_spec);
  793. #endif
  794. if (timeptr == NULL)
  795. {
  796. #if !defined(HAVE_GMTIME_R) && defined(MUTEX_LOCKS_AVAILABLE)
  797. privoxy_mutex_unlock(&gmtime_mutex);
  798. #endif
  799. return NULL;
  800. }
  801. #if !defined(HAVE_GMTIME_R)
  802. *result = *timeptr;
  803. timeptr = result;
  804. #ifdef MUTEX_LOCKS_AVAILABLE
  805. privoxy_mutex_unlock(&gmtime_mutex);
  806. #endif
  807. #endif
  808. return timeptr;
  809. }
  810. #if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
  811. /*********************************************************************
  812. *
  813. * Function : timegm
  814. *
  815. * Description : libc replacement function for the inverse of gmtime().
  816. * Copyright (C) 2004 Free Software Foundation, Inc.
  817. *
  818. * Code originally copied from GnuPG, modifications done
  819. * for Privoxy: style changed, #ifdefs for _WIN32 added
  820. * to have it work on mingw32.
  821. *
  822. * XXX: It's very unlikely to happen, but if the malloc()
  823. * call fails the time zone will be permanently set to UTC.
  824. *
  825. * Parameters :
  826. * 1 : tm: Broken-down time struct.
  827. *
  828. * Returns : tm converted into time_t seconds.
  829. *
  830. *********************************************************************/
  831. time_t timegm(struct tm *tm)
  832. {
  833. time_t answer;
  834. char *zone;
  835. zone = getenv("TZ");
  836. putenv("TZ=UTC");
  837. tzset();
  838. answer = mktime(tm);
  839. if (zone)
  840. {
  841. char *old_zone;
  842. old_zone = malloc(3 + strlen(zone) + 1);
  843. if (old_zone)
  844. {
  845. strcpy(old_zone, "TZ=");
  846. strcat(old_zone, zone);
  847. putenv(old_zone);
  848. #ifdef _WIN32
  849. /* http://man7.org/linux/man-pages/man3/putenv.3.html
  850. * int putenv(char *string);
  851. * The string pointed to by string becomes part of the environment, so altering the
  852. * string changes the environment.
  853. * In other words, the memory pointed to by *string is used until
  854. * a) another call to putenv() with the same e-var name
  855. * b) the program exits
  856. *
  857. * Windows e-vars don't work that way, so let's not leak memory.
  858. */
  859. free(old_zone);
  860. #endif /* def _WIN32 */
  861. }
  862. }
  863. else
  864. {
  865. #ifdef HAVE_UNSETENV
  866. unsetenv("TZ");
  867. #elif defined(_WIN32)
  868. putenv("TZ=");
  869. #else
  870. putenv("TZ");
  871. #endif
  872. }
  873. tzset();
  874. return answer;
  875. }
  876. #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
  877. /*
  878. Local Variables:
  879. tab-width: 3
  880. end:
  881. */