1 /*********************************************************************
3 * File : $Source: /cvsroot/ijbswa/current/miscutil.c,v $
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
10 * Copyright : Written by and Copyright (C) 2001-2020 the
11 * Privoxy team. https://www.privoxy.org/
13 * Based on the Internet Junkbuster originally written
14 * by and Copyright (C) 1997 Anonymous Coders and
15 * Junkbusters Corporation. http://www.junkbusters.com
17 * The timegm replacement function was taken from GnuPG,
18 * Copyright (C) 2004 Free Software Foundation, Inc.
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.
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.
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.
38 *********************************************************************/
44 #include <sys/types.h>
48 #endif /* #if !defined(_WIN32) */
53 #if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
55 #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
62 /*********************************************************************
66 * Description : Returns allocated memory that is initialized
70 * 1 : size = Size of memory chunk to return.
72 * Returns : Pointer to newly alloc'd memory chunk.
74 *********************************************************************/
75 void *zalloc(size_t size)
80 ret = calloc(1, size);
82 #warning calloc appears to be unavailable. Your platform will become unsupported in the future
83 if ((ret = (void *)malloc(size)) != NULL)
94 /*********************************************************************
96 * Function : zalloc_or_die
98 * Description : zalloc wrapper that either succeeds or causes
99 * program termination.
101 * Useful in situations were the string length is
102 * "small" and zalloc() failures couldn't be handled
103 * better anyway. In case of debug builds, failures
104 * trigger an assert().
107 * 1 : size = Size of memory chunk to return.
109 * Returns : Pointer to newly malloc'd memory chunk.
111 *********************************************************************/
112 void *zalloc_or_die(size_t size)
116 buffer = zalloc(size);
119 assert(buffer != NULL);
120 log_error(LOG_LEVEL_FATAL, "Out of memory in zalloc_or_die().");
128 /*********************************************************************
130 * Function : strdup_or_die
132 * Description : strdup wrapper that either succeeds or causes
133 * program termination.
135 * Useful in situations were the string length is
136 * "small" and strdup() failures couldn't be handled
137 * better anyway. In case of debug builds, failures
138 * trigger an assert().
141 * 1 : str = String to duplicate
143 * Returns : Pointer to newly strdup'd copy of the string.
145 *********************************************************************/
146 char *strdup_or_die(const char *str)
150 new_str = strdup(str);
154 assert(new_str != NULL);
155 log_error(LOG_LEVEL_FATAL, "Out of memory in strdup_or_die().");
164 /*********************************************************************
166 * Function : malloc_or_die
168 * Description : malloc wrapper that either succeeds or causes
169 * program termination.
171 * Useful in situations were the buffer size is "small"
172 * and malloc() failures couldn't be handled better
173 * anyway. In case of debug builds, failures trigger
177 * 1 : buffer_size = Size of the space to allocate
179 * Returns : Pointer to newly malloc'd memory
181 *********************************************************************/
182 void *malloc_or_die(size_t buffer_size)
186 if (buffer_size == 0)
188 log_error(LOG_LEVEL_ERROR,
189 "malloc_or_die() called with buffer size 0");
190 assert(buffer_size != 0);
194 new_buf = malloc(buffer_size);
198 assert(new_buf != NULL);
199 log_error(LOG_LEVEL_FATAL, "Out of memory in malloc_or_die().");
209 /*********************************************************************
211 * Function : write_pid_file
213 * Description : Writes a pid file with the pid of the main process.
214 * Exits if the file can't be opened
217 * 1 : pid_file = Path of the pid file that gets created.
221 *********************************************************************/
222 void write_pid_file(const char *pid_file)
226 if ((fp = fopen(pid_file, "w")) == NULL)
228 log_error(LOG_LEVEL_FATAL, "can't open pid file '%s': %E", pid_file);
232 fprintf(fp, "%u\n", (unsigned int) getpid());
238 #endif /* def unix */
241 /*********************************************************************
243 * Function : hash_string
245 * Description : Take a string and compute a (hopefully) unique numeric
246 * integer value. This is useful to "switch" a string.
249 * 1 : s : string to be hashed.
251 * Returns : The string's hash
253 *********************************************************************/
254 unsigned int hash_string(const char* s)
260 h = 5 * h + (unsigned int)*s;
268 /*********************************************************************
270 * Function : strcmpic
272 * Description : Case insensitive string comparison
275 * 1 : s1 = string 1 to compare
276 * 2 : s2 = string 2 to compare
278 * Returns : 0 if s1==s2, Negative if s1<s2, Positive if s1>s2
280 *********************************************************************/
281 int strcmpic(const char *s1, const char *s2)
288 if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2)))
294 return(privoxy_tolower(*s1) - privoxy_tolower(*s2));
299 /*********************************************************************
301 * Function : strncmpic
303 * Description : Case insensitive string comparison (up to n characters)
306 * 1 : s1 = string 1 to compare
307 * 2 : s2 = string 2 to compare
308 * 3 : n = maximum characters to compare
310 * Returns : 0 if s1==s2, Negative if s1<s2, Positive if s1>s2
312 *********************************************************************/
313 int strncmpic(const char *s1, const char *s2, size_t n)
315 if (n <= (size_t)0) return(0);
321 if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2)))
326 if (--n <= (size_t)0) break;
330 return(privoxy_tolower(*s1) - privoxy_tolower(*s2));
335 /*********************************************************************
339 * Description : In-situ-eliminate all leading and trailing whitespace
343 * 1 : s : string to be chomped.
345 * Returns : chomped string
347 *********************************************************************/
348 char *chomp(char *string)
353 * strip trailing whitespace
355 p = string + strlen(string);
356 while (p > string && privoxy_isspace(*(p-1)))
363 * find end of leading whitespace
366 while (*q && privoxy_isspace(*q))
372 * if there was any, move the rest forwards
387 /*********************************************************************
389 * Function : string_append
391 * Description : Reallocate target_string and append text to it.
392 * This makes it easier to append to malloc'd strings.
393 * This is similar to the (removed) strsav(), but
394 * running out of memory isn't catastrophic.
398 * The following style provides sufficient error
399 * checking for this routine, with minimal clutter
400 * in the source code. It is recommended if you
401 * have many calls to this function:
403 * char * s = strdup(...); // don't check for error
404 * string_append(&s, ...); // don't check for error
405 * string_append(&s, ...); // don't check for error
406 * string_append(&s, ...); // don't check for error
407 * if (NULL == s) { ... handle error ... }
411 * char * s = strdup(...); // don't check for error
412 * string_append(&s, ...); // don't check for error
413 * string_append(&s, ...); // don't check for error
414 * if (string_append(&s, ...)) {... handle error ...}
417 * 1 : target_string = Pointer to old text that is to be
418 * extended. *target_string will be free()d by this
419 * routine. target_string must be non-NULL.
420 * If *target_string is NULL, this routine will
421 * do nothing and return with an error - this allows
422 * you to make many calls to this routine and only
423 * check for errors after the last one.
424 * 2 : text_to_append = Text to be appended to old.
427 * Returns : JB_ERR_OK on success, and sets *target_string
428 * to newly malloc'ed appended string. Caller
429 * must free(*target_string).
430 * JB_ERR_MEMORY on out-of-memory. (And free()s
431 * *target_string and sets it to NULL).
432 * JB_ERR_MEMORY if *target_string is NULL.
434 *********************************************************************/
435 jb_err string_append(char **target_string, const char *text_to_append)
441 assert(target_string);
442 assert(text_to_append);
444 if (*target_string == NULL)
446 return JB_ERR_MEMORY;
449 if (*text_to_append == '\0')
454 old_len = strlen(*target_string);
456 new_size = strlen(text_to_append) + old_len + 1;
458 if (NULL == (new_string = realloc(*target_string, new_size)))
460 free(*target_string);
462 *target_string = NULL;
463 return JB_ERR_MEMORY;
466 strlcpy(new_string + old_len, text_to_append, new_size - old_len);
468 *target_string = new_string;
473 /*********************************************************************
475 * Function : string_join
477 * Description : Join two strings together. Frees BOTH the original
478 * strings. If either or both input strings are NULL,
479 * fails as if it had run out of memory.
481 * For comparison, string_append requires that the
482 * second string is non-NULL, and doesn't free it.
484 * Rationale: Too often, we want to do
485 * string_append(s, html_encode(s2)). That assert()s
486 * if s2 is NULL or if html_encode() runs out of memory.
487 * It also leaks memory. Proper checking is cumbersome.
488 * The solution: string_join(s, html_encode(s2)) is safe,
489 * and will free the memory allocated by html_encode().
492 * 1 : target_string = Pointer to old text that is to be
493 * extended. *target_string will be free()d by this
494 * routine. target_string must be non-NULL.
495 * 2 : text_to_append = Text to be appended to old.
497 * Returns : JB_ERR_OK on success, and sets *target_string
498 * to newly malloc'ed appended string. Caller
499 * must free(*target_string).
500 * JB_ERR_MEMORY on out-of-memory, or if
501 * *target_string or text_to_append is NULL. (In
502 * this case, frees *target_string and text_to_append,
503 * sets *target_string to NULL).
505 *********************************************************************/
506 jb_err string_join(char **target_string, char *text_to_append)
510 assert(target_string);
512 if (text_to_append == NULL)
514 freez(*target_string);
515 return JB_ERR_MEMORY;
518 err = string_append(target_string, text_to_append);
520 freez(text_to_append);
526 /*********************************************************************
528 * Function : string_toupper
530 * Description : Produce a copy of string with all convertible
531 * characters converted to uppercase.
534 * 1 : string = string to convert
536 * Returns : Uppercase copy of string if possible,
537 * NULL on out-of-memory or if string was NULL.
539 *********************************************************************/
540 char *string_toupper(const char *string)
545 if (!string || ((result = (char *) zalloc(strlen(string) + 1)) == NULL))
555 *p++ = (char)toupper((int) *q++);
563 /*********************************************************************
565 * Function : string_tolower
567 * Description : Produce a copy of string with all convertible
568 * characters converted to lowercase.
571 * 1 : string = string to convert
573 * Returns : Lowercase copy of string if possible,
574 * NULL on out-of-memory or if string was NULL.
576 *********************************************************************/
577 char *string_tolower(const char *string)
582 if (!string || ((result = (char *)zalloc(strlen(string) + 1)) == NULL))
592 *p++ = (char)privoxy_tolower(*q++);
600 /*********************************************************************
602 * Function : string_move
604 * Description : memmove wrapper to move the last part of a string
605 * towards the beginning, overwriting the part in
606 * the middle. strlcpy() can't be used here as the
610 * 1 : dst = Destination to overwrite
611 * 2 : src = Source to move.
615 *********************************************************************/
616 void string_move(char *dst, char *src)
620 /* +1 to copy the terminating nul as well. */
621 memmove(dst, src, strlen(src)+1);
625 /*********************************************************************
629 * Description : Duplicate the first n characters of a string that may
630 * contain '\0' characters.
633 * 1 : string = string to be duplicated
634 * 2 : len = number of bytes to duplicate
636 * Returns : pointer to copy, or NULL if failure
638 *********************************************************************/
639 char *bindup(const char *string, size_t len)
643 duplicate = (char *)malloc(len);
644 if (NULL != duplicate)
646 memcpy(duplicate, string, len);
654 /*********************************************************************
656 * Function : make_path
658 * Description : Takes a directory name and a file name, returns
659 * the complete path. Handles windows/unix differences.
660 * If the file name is already an absolute path, or if
661 * the directory name is NULL or empty, it returns
665 * 1 : dir: Name of directory or NULL for none.
666 * 2 : file: Name of file. Should not be NULL or empty.
668 * Returns : "dir/file" (Or on windows, "dir\file").
669 * It allocates the string on the heap. Caller frees.
670 * Returns NULL in error (i.e. NULL file or out of
673 *********************************************************************/
674 char * make_path(const char * dir, const char * file)
676 if ((file == NULL) || (*file == '\0'))
678 return NULL; /* Error */
681 if ((dir == NULL) || (*dir == '\0') /* No directory specified */
683 || (*file == '\\') || (file[1] == ':') /* Absolute path (DOS) */
684 #else /* ifndef _WIN32 */
685 || (*file == '/') /* Absolute path (U*ix) */
686 #endif /* ifndef _WIN32 */
694 size_t path_size = strlen(dir) + strlen(file) + 2; /* +2 for trailing (back)slash and \0 */
697 if (*dir != '/' && basedir && *basedir)
700 * Relative path, so start with the base directory.
702 path_size += strlen(basedir) + 1; /* +1 for the slash */
703 path = malloc(path_size);
704 if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
705 strlcpy(path, basedir, path_size);
706 strlcat(path, "/", path_size);
707 strlcat(path, dir, path_size);
710 #endif /* defined unix */
712 path = malloc(path_size);
713 if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
714 strlcpy(path, dir, path_size);
717 assert(NULL != path);
719 if (path[strlen(path)-1] != '\\')
721 strlcat(path, "\\", path_size);
723 #else /* ifndef _WIN32 */
724 if (path[strlen(path)-1] != '/')
726 strlcat(path, "/", path_size);
728 #endif /* ifndef _WIN32 */
729 strlcat(path, file, path_size);
736 /*********************************************************************
738 * Function : pick_from_range
740 * Description : Pick a positive number out of a given range.
741 * Should only be used if randomness would be nice,
742 * but isn't really necessary.
745 * 1 : range: Highest possible number to pick.
747 * Returns : Picked number.
749 *********************************************************************/
750 long int pick_from_range(long int range)
754 static unsigned long seed = 0;
755 #endif /* def _WIN32 */
760 if (range <= 0) return 0;
762 #ifdef HAVE_ARC4RANDOM
763 number = arc4random() % range + 1;
764 #elif defined(HAVE_RANDOM)
765 number = random() % range + 1;
766 #elif defined(MUTEX_LOCKS_AVAILABLE)
767 privoxy_mutex_lock(&rand_mutex);
771 seed = (unsigned long)(GetCurrentThreadId()+GetTickCount());
774 seed = (unsigned long)((rand() << 16) + rand());
775 #endif /* def _WIN32 */
776 number = (unsigned long)((rand() << 16) + (rand())) % (unsigned long)(range + 1);
777 privoxy_mutex_unlock(&rand_mutex);
780 * XXX: Which platforms reach this and are there
781 * better options than just using rand() and hoping
784 log_error(LOG_LEVEL_INFO, "No thread-safe PRNG available? Header time randomization "
785 "might cause crashes, predictable results or even combine these fine options.");
786 number = rand() % (long int)(range + 1);
788 #endif /* (def HAVE_ARC4RANDOM) */
794 #ifdef USE_PRIVOXY_STRLCPY
795 /*********************************************************************
797 * Function : privoxy_strlcpy
799 * Description : strlcpy(3) look-alike for those without decent libc.
802 * 1 : destination: buffer to copy into.
803 * 2 : source: String to copy.
804 * 3 : size: Size of destination buffer.
806 * Returns : The length of the string that privoxy_strlcpy() tried to create.
808 *********************************************************************/
809 size_t privoxy_strlcpy(char *destination, const char *source, const size_t size)
813 snprintf(destination, size, "%s", source);
815 * Platforms that lack strlcpy() also tend to have
816 * a broken snprintf implementation that doesn't
817 * guarantee nul termination.
819 * XXX: the configure script should detect and reject those.
821 destination[size-1] = '\0';
823 return strlen(source);
825 #endif /* def USE_PRIVOXY_STRLCPY */
829 /*********************************************************************
831 * Function : privoxy_strlcat
833 * Description : strlcat(3) look-alike for those without decent libc.
836 * 1 : destination: C string.
837 * 2 : source: String to copy.
838 * 3 : size: Size of destination buffer.
840 * Returns : The length of the string that privoxy_strlcat() tried to create.
842 *********************************************************************/
843 size_t privoxy_strlcat(char *destination, const char *source, const size_t size)
845 const size_t old_length = strlen(destination);
846 return old_length + strlcpy(destination + old_length, source, size - old_length);
848 #endif /* ndef HAVE_STRLCAT */
851 /*********************************************************************
853 * Function : privoxy_millisleep
855 * Description : Sleep a number of milliseconds
858 * 1 : delay: Number of milliseconds to sleep
860 * Returns : -1 on error, 0 otherwise
862 *********************************************************************/
863 int privoxy_millisleep(unsigned milliseconds)
865 #ifdef HAVE_NANOSLEEP
866 struct timespec rqtp = {0};
867 struct timespec rmtp = {0};
869 rqtp.tv_sec = milliseconds / 1000;
870 rqtp.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
872 return nanosleep(&rqtp, &rmtp);
873 #elif defined (_WIN32)
878 #warning Missing privoxy_milisleep() implementation. delay-response{} will not work.
881 #endif /* def HAVE_NANOSLEEP */
886 /*********************************************************************
888 * Function : privoxy_gmtime_r
890 * Description : Behave like gmtime_r() and convert a
891 * time_t to a struct tm.
894 * 1 : time_spec: The time to convert
895 * 2 : result: The struct tm to use as storage
897 * Returns : Pointer to the result or NULL on error.
899 *********************************************************************/
900 struct tm *privoxy_gmtime_r(const time_t *time_spec, struct tm *result)
905 timeptr = gmtime_r(time_spec, result);
906 #elif defined(MUTEX_LOCKS_AVAILABLE)
907 privoxy_mutex_lock(&gmtime_mutex);
908 timeptr = gmtime(time_spec);
910 #warning Using unlocked gmtime()
911 timeptr = gmtime(time_spec);
916 #if !defined(HAVE_GMTIME_R) && defined(MUTEX_LOCKS_AVAILABLE)
917 privoxy_mutex_unlock(&gmtime_mutex);
922 #if !defined(HAVE_GMTIME_R)
925 #ifdef MUTEX_LOCKS_AVAILABLE
926 privoxy_mutex_unlock(&gmtime_mutex);
933 #if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
934 /*********************************************************************
938 * Description : libc replacement function for the inverse of gmtime().
939 * Copyright (C) 2004 Free Software Foundation, Inc.
941 * Code originally copied from GnuPG, modifications done
942 * for Privoxy: style changed, #ifdefs for _WIN32 added
943 * to have it work on mingw32.
945 * XXX: It's very unlikely to happen, but if the malloc()
946 * call fails the time zone will be permanently set to UTC.
949 * 1 : tm: Broken-down time struct.
951 * Returns : tm converted into time_t seconds.
953 *********************************************************************/
954 time_t timegm(struct tm *tm)
967 old_zone = malloc(3 + strlen(zone) + 1);
970 strcpy(old_zone, "TZ=");
971 strcat(old_zone, zone);
974 /* http://man7.org/linux/man-pages/man3/putenv.3.html
975 * int putenv(char *string);
976 * The string pointed to by string becomes part of the environment, so altering the
977 * string changes the environment.
978 * In other words, the memory pointed to by *string is used until
979 * a) another call to putenv() with the same e-var name
980 * b) the program exits
982 * Windows e-vars don't work that way, so let's not leak memory.
985 #endif /* def _WIN32 */
992 #elif defined(_WIN32)
1002 #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
1005 /*********************************************************************
1007 * Function : host_is_ip_address
1009 * Description : Checks whether or not a host is specified by
1010 * IP address. Does not actually validate the
1014 * 1 : host = The host name to check
1016 * Returns : 1 => Yes
1019 *********************************************************************/
1020 extern int host_is_ip_address(const char *host)
1024 if (NULL != strstr(host, ":"))
1026 /* Assume an IPv6 address. */
1030 for (p = host; *p; p++)
1032 if ((*p != '.') && !privoxy_isdigit(*p))
1034 /* Not a dot or digit so it can't be an IPv4 address. */
1040 * Host only consists of dots and digits so
1041 * assume that is an IPv4 address.