X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=miscutil.c;h=10ff9ead4f58c2cd7d519964c46bf16b1ba9a2e4;hp=b64fd4f7ba9b9ddf07d07c622abadf206927bda1;hb=983ba27e15f4691702d498b14f6c1459254bcc78;hpb=c3304436248b6e11a90d2f16eb4f7f68b391a74f diff --git a/miscutil.c b/miscutil.c index b64fd4f7..10ff9ead 100644 --- a/miscutil.c +++ b/miscutil.c @@ -1,19 +1,18 @@ -const char miscutil_rcs[] = "$Id: miscutil.c,v 1.63 2009/05/16 13:27:20 fabiankeil Exp $"; +const char miscutil_rcs[] = "$Id: miscutil.c,v 1.81 2016/02/26 12:29:17 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/miscutil.c,v $ * - * Purpose : zalloc, hash_string, safe_strerror, strcmpic, - * strncmpic, chomp, and MinGW32 strdup - * functions. - * These are each too small to deserve their own file - * but don't really fit in any other file. + * Purpose : zalloc, hash_string, strcmpic, strncmpic, and + * MinGW32 strdup functions. These are each too small + * to deserve their own file but don't really fit in + * any other file. * - * Copyright : Written by and Copyright (C) 2001-2007 - * the SourceForge Privoxy team. http://www.privoxy.org/ + * Copyright : Written by and Copyright (C) 2001-2016 the + * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and + * by and Copyright (C) 1997 Anonymous Coders and * Junkbusters Corporation. http://www.junkbusters.com * * The timegm replacement function was taken from GnuPG, @@ -24,7 +23,7 @@ const char miscutil_rcs[] = "$Id: miscutil.c,v 1.63 2009/05/16 13:27:20 fabianke * used under the terms of the GPL or the terms of the * "Frontier Artistic License". * - * This program is free software; you can redistribute it + * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software * Foundation; either version 2 of the License, or (at @@ -73,7 +72,6 @@ const char miscutil_h_rcs[] = MISCUTIL_H_VERSION; * Function : zalloc * * Description : Malloc some memory and set it to '\0'. - * The way calloc() ought to be -acjc * * Parameters : * 1 : size = Size of memory chunk to return. @@ -95,136 +93,180 @@ void *zalloc(size_t size) } -#if defined(unix) /********************************************************************* * - * Function : write_pid_file + * Function : zalloc_or_die * - * Description : Writes a pid file with the pid of the main process + * Description : zalloc wrapper that either succeeds or causes + * program termination. * - * Parameters : None + * Useful in situations were the string length is + * "small" and zalloc() failures couldn't be handled + * better anyway. In case of debug builds, failures + * trigger an assert(). * - * Returns : N/A + * Parameters : + * 1 : size = Size of memory chunk to return. + * + * Returns : Pointer to newly malloc'd memory chunk. * *********************************************************************/ -void write_pid_file(void) +void *zalloc_or_die(size_t size) { - FILE *fp; - - /* - * If no --pidfile option was given, - * we can live without one. - */ - if (pidfile == NULL) return; + void *buffer; - if ((fp = fopen(pidfile, "w")) == NULL) - { - log_error(LOG_LEVEL_INFO, "can't open pidfile '%s': %E", pidfile); - } - else + buffer = zalloc(size); + if (buffer == NULL) { - fprintf(fp, "%u\n", (unsigned int) getpid()); - fclose (fp); + assert(buffer != NULL); + log_error(LOG_LEVEL_FATAL, "Out of memory in zalloc_or_die()."); + exit(1); } - return; -} -#endif /* def unix */ + return(buffer); +} /********************************************************************* * - * Function : hash_string + * Function : strdup_or_die * - * Description : Take a string and compute a (hopefuly) unique numeric - * integer value. This has several uses, but being able - * to "switch" a string the one of my favorites. + * Description : strdup wrapper that either succeeds or causes + * program termination. + * + * Useful in situations were the string length is + * "small" and strdup() failures couldn't be handled + * better anyway. In case of debug builds, failures + * trigger an assert(). * * Parameters : - * 1 : s : string to be hashed. + * 1 : str = String to duplicate * - * Returns : an unsigned long variable with the hashed value. + * Returns : Pointer to newly strdup'd copy of the string. * *********************************************************************/ -unsigned int hash_string( const char* s ) +char *strdup_or_die(const char *str) { - unsigned int h = 0; + char *new_str; + + new_str = strdup(str); - for ( ; *s; ++s ) + if (new_str == NULL) { - h = 5 * h + (unsigned int)*s; + assert(new_str != NULL); + log_error(LOG_LEVEL_FATAL, "Out of memory in strdup_or_die()."); + exit(1); } - return (h); + return(new_str); } -#ifdef __MINGW32__ /********************************************************************* * - * Function : strdup + * Function : malloc_or_die + * + * Description : malloc wrapper that either succeeds or causes + * program termination. * - * Description : For some reason (which is beyond me), gcc and WIN32 - * don't like strdup. When a "free" is executed on a - * strdup'd ptr, it can at times freez up! So I just - * replaced it and problem was solved. + * Useful in situations were the buffer size is "small" + * and malloc() failures couldn't be handled better + * anyway. In case of debug builds, failures trigger + * an assert(). * * Parameters : - * 1 : s = string to duplicate + * 1 : buffer_size = Size of the space to allocate * - * Returns : Pointer to newly malloc'ed copy of the string. + * Returns : Pointer to newly malloc'd memory * *********************************************************************/ -char *strdup( const char *s ) +void *malloc_or_die(size_t buffer_size) { - char * result = (char *)malloc( strlen(s)+1 ); + char *new_buf; - if (result != NULL) + if (buffer_size == 0) { - strcpy( result, s ); + log_error(LOG_LEVEL_ERROR, + "malloc_or_die() called with buffer size 0"); + assert(buffer_size != 0); + buffer_size = 4096; } - return( result ); -} + new_buf = malloc(buffer_size); + + if (new_buf == NULL) + { + assert(new_buf != NULL); + log_error(LOG_LEVEL_FATAL, "Out of memory in malloc_or_die()."); + exit(1); + } -#endif /* def __MINGW32__ */ + return(new_buf); +} +#if defined(unix) /********************************************************************* * - * Function : safe_strerror + * Function : write_pid_file * - * Description : Variant of the library routine strerror() which will - * work on systems without the library routine, and - * which should never return NULL. + * Description : Writes a pid file with the pid of the main process * - * Parameters : - * 1 : err = the `errno' of the last operation. + * Parameters : None * - * Returns : An "English" string of the last `errno'. Allocated - * with strdup(), so caller frees. May be NULL if the - * system is out of memory. + * Returns : N/A * *********************************************************************/ -char *safe_strerror(int err) +void write_pid_file(void) { - char *s = NULL; - char buf[BUFFER_SIZE]; + FILE *fp; + /* + * If no --pidfile option was given, + * we can live without one. + */ + if (pidfile == NULL) return; -#ifdef HAVE_STRERROR - s = strerror(err); -#endif /* HAVE_STRERROR */ + if ((fp = fopen(pidfile, "w")) == NULL) + { + log_error(LOG_LEVEL_INFO, "can't open pidfile '%s': %E", pidfile); + } + else + { + fprintf(fp, "%u\n", (unsigned int) getpid()); + fclose (fp); + } + return; - if (s == NULL) +} +#endif /* def unix */ + + +/********************************************************************* + * + * Function : hash_string + * + * Description : Take a string and compute a (hopefuly) unique numeric + * integer value. This is useful to "switch" a string. + * + * Parameters : + * 1 : s : string to be hashed. + * + * Returns : The string's hash + * + *********************************************************************/ +unsigned int hash_string(const char* s) +{ + unsigned int h = 0; + + for (; *s; ++s) { - snprintf(buf, sizeof(buf), "(errno = %d)", err); - s = buf; + h = 5 * h + (unsigned int)*s; } - return(strdup(s)); + return (h); } @@ -249,13 +291,13 @@ int strcmpic(const char *s1, const char *s2) while (*s1 && *s2) { - if ( ( *s1 != *s2 ) && ( ijb_tolower(*s1) != ijb_tolower(*s2) ) ) + if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2))) { break; } s1++, s2++; } - return(ijb_tolower(*s1) - ijb_tolower(*s2)); + return(privoxy_tolower(*s1) - privoxy_tolower(*s2)); } @@ -264,7 +306,7 @@ int strcmpic(const char *s1, const char *s2) * * Function : strncmpic * - * Description : Case insensitive string comparison (upto n characters) + * Description : Case insensitive string comparison (up to n characters) * * Parameters : * 1 : s1 = string 1 to compare @@ -279,10 +321,10 @@ int strncmpic(const char *s1, const char *s2, size_t n) if (n <= (size_t)0) return(0); if (!s1) s1 = ""; if (!s2) s2 = ""; - + while (*s1 && *s2) { - if ( ( *s1 != *s2 ) && ( ijb_tolower(*s1) != ijb_tolower(*s2) ) ) + if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2))) { break; } @@ -291,7 +333,7 @@ int strncmpic(const char *s1, const char *s2, size_t n) s1++, s2++; } - return(ijb_tolower(*s1) - ijb_tolower(*s2)); + return(privoxy_tolower(*s1) - privoxy_tolower(*s2)); } @@ -313,21 +355,21 @@ char *chomp(char *string) { char *p, *q, *r; - /* + /* * strip trailing whitespace */ p = string + strlen(string); - while (p > string && ijb_isspace(*(p-1))) + while (p > string && privoxy_isspace(*(p-1))) { p--; } *p = '\0'; - /* - * find end of leading whitespace + /* + * find end of leading whitespace */ q = r = string; - while (*q && ijb_isspace(*q)) + while (*q && privoxy_isspace(*q)) { q++; } @@ -352,7 +394,7 @@ char *chomp(char *string) * * Function : string_append * - * Description : Reallocate target_string and append text to it. + * Description : Reallocate target_string and append text to it. * This makes it easier to append to malloc'd strings. * This is similar to the (removed) strsav(), but * running out of memory isn't catastrophic. @@ -497,7 +539,7 @@ jb_err string_join(char **target_string, char *text_to_append) * Parameters : * 1 : string = string to convert * - * Returns : Uppercase copy of string if possible, + * Returns : Uppercase copy of string if possible, * NULL on out-of-memory or if string was NULL. * *********************************************************************/ @@ -510,7 +552,7 @@ char *string_toupper(const char *string) { return NULL; } - + q = string; p = result; @@ -524,6 +566,31 @@ char *string_toupper(const char *string) } +/********************************************************************* + * + * Function : string_move + * + * Description : memmove wrapper to move the last part of a string + * towards the beginning, overwriting the part in + * the middle. strlcpy() can't be used here as the + * strings overlap. + * + * Parameters : + * 1 : dst = Destination to overwrite + * 2 : src = Source to move. + * + * Returns : N/A + * + *********************************************************************/ +void string_move(char *dst, char *src) +{ + assert(dst < src); + + /* +1 to copy the terminating nul as well. */ + memmove(dst, src, strlen(src)+1); +} + + /********************************************************************* * * Function : bindup @@ -542,13 +609,10 @@ char *bindup(const char *string, size_t len) { char *duplicate; - if (NULL == (duplicate = (char *)malloc(len))) + duplicate = (char *)malloc(len); + if (NULL != duplicate) { - return NULL; - } - else - { - memcpy(duplicate, string, len); + memcpy(duplicate, string, len); } return duplicate; @@ -560,11 +624,11 @@ char *bindup(const char *string, size_t len) * * Function : make_path * - * Description : Takes a directory name and a file name, returns + * Description : Takes a directory name and a file name, returns * the complete path. Handles windows/unix differences. * If the file name is already an absolute path, or if - * the directory name is NULL or empty, it returns - * the filename. + * the directory name is NULL or empty, it returns + * the filename. * * Parameters : * 1 : dir: Name of directory or NULL for none. @@ -573,7 +637,7 @@ char *bindup(const char *string, size_t len) * Returns : "dir/file" (Or on windows, "dir\file"). * It allocates the string on the heap. Caller frees. * Returns NULL in error (i.e. NULL file or out of - * memory) + * memory) * *********************************************************************/ char * make_path(const char * dir, const char * file) @@ -581,11 +645,11 @@ char * make_path(const char * dir, const char * file) #ifdef AMIGA char path[512]; - if(dir) + if (dir) { - if(dir[0] == '.') + if (dir[0] == '.') { - if(dir[1] == '/') + if (dir[1] == '/') { strncpy(path,dir+2,512); } @@ -604,7 +668,7 @@ char * make_path(const char * dir, const char * file) { path[0]=0; } - if(AddPart(path,file,512)) + if (AddPart(path,file,512)) { return strdup(path); } @@ -635,14 +699,14 @@ char * make_path(const char * dir, const char * file) size_t path_size = strlen(dir) + strlen(file) + 2; /* +2 for trailing (back)slash and \0 */ #if defined(unix) - if ( *dir != '/' && basedir && *basedir ) + if (*dir != '/' && basedir && *basedir) { /* * Relative path, so start with the base directory. */ path_size += strlen(basedir) + 1; /* +1 for the slash */ path = malloc(path_size); - if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!"); + if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!"); strlcpy(path, basedir, path_size); strlcat(path, "/", path_size); strlcat(path, dir, path_size); @@ -651,18 +715,18 @@ char * make_path(const char * dir, const char * file) #endif /* defined unix */ { path = malloc(path_size); - if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!"); + if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!"); strlcpy(path, dir, path_size); } assert(NULL != path); #if defined(_WIN32) || defined(__OS2__) - if(path[strlen(path)-1] != '\\') + if (path[strlen(path)-1] != '\\') { strlcat(path, "\\", path_size); } #else /* ifndef _WIN32 || __OS2__ */ - if(path[strlen(path)-1] != '/') + if (path[strlen(path)-1] != '/') { strlcat(path, "/", path_size); } @@ -686,7 +750,7 @@ char * make_path(const char * dir, const char * file) * Parameters : * 1 : range: Highest possible number to pick. * - * Returns : Picked number. + * Returns : Picked number. * *********************************************************************/ long int pick_from_range(long int range) @@ -702,7 +766,7 @@ long int pick_from_range(long int range) if (range <= 0) return 0; #ifdef HAVE_RANDOM - number = random() % range + 1; + number = random() % range + 1; #elif defined(MUTEX_LOCKS_AVAILABLE) privoxy_mutex_lock(&rand_mutex); #ifdef _WIN32 @@ -806,7 +870,7 @@ size_t privoxy_strlcat(char *destination, const char *source, const size_t size) * Parameters : * 1 : tm: Broken-down time struct. * - * Returns : tm converted into time_t seconds. + * Returns : tm converted into time_t seconds. * *********************************************************************/ time_t timegm(struct tm *tm) @@ -829,6 +893,16 @@ time_t timegm(struct tm *tm) strcat(old_zone, zone); putenv(old_zone); #ifdef _WIN32 + /* http://man7.org/linux/man-pages/man3/putenv.3.html + * int putenv(char *string); + * The string pointed to by string becomes part of the environment, so altering the + * string changes the environment. + * In other words, the memory pointed to by *string is used until + * a) another call to putenv() with the same e-var name + * b) the program exits + * + * Windows e-vars don't work that way, so let's not leak memory. + */ free(old_zone); #endif /* def _WIN32 */ } @@ -858,7 +932,7 @@ time_t timegm(struct tm *tm) snprintf.c - a portable implementation of snprintf, including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf - + snprintf is a routine to convert numeric and string arguments to formatted strings. It is similar to sprintf(3) provided in a system's C library, yet it requires an additional argument - the buffer size - @@ -1500,7 +1574,7 @@ int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { } } /* zero padding to specified precision? */ - if (num_of_digits < precision) + if (num_of_digits < precision) number_of_zeros_to_pad = precision - num_of_digits; } /* zero padding to specified minimal field width? */ @@ -1518,7 +1592,7 @@ int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { #if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) /* keep the entire format string unchanged */ str_arg = starting_p; str_arg_l = p - starting_p; - /* well, not exactly so for Linux, which does something inbetween, + /* well, not exactly so for Linux, which does something between, * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ #else /* discard the unrecognized conversion, just keep *