-const char miscutil_rcs[] = "$Id: miscutil.c,v 1.43 2006/09/23 13:26:38 roro Exp $";
+const char miscutil_rcs[] = "$Id: miscutil.c,v 1.66 2011/05/22 10:26:45 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 the SourceForge
+ * Copyright : Written by and Copyright (C) 2001-2011 the
* Privoxy team. http://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
* by and Copyright (C) 1997 Anonymous Coders and
* Junkbusters Corporation. http://www.junkbusters.com
*
+ * The timegm replacement function was taken from GnuPG,
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * The snprintf replacement function is written by
+ * Mark Martinec who also holds the copyright. It can be
+ * used under the terms of the GPL or the terms of the
+ * "Frontier Artistic License".
+ *
* 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
* or write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Revisions :
- * $Log: miscutil.c,v $
- * Revision 1.43 2006/09/23 13:26:38 roro
- * Replace TABs by spaces in source code.
- *
- * Revision 1.42 2006/09/09 14:01:45 fabiankeil
- * Integrated Oliver Yeoh's domain pattern fix
- * to make sure *x matches xx. Closes Patch 1217393
- * and Bug 1170767.
- *
- * Revision 1.41 2006/08/18 16:03:17 david__schmidt
- * Tweak for OS/2 build happiness.
- *
- * Revision 1.40 2006/08/17 17:15:10 fabiankeil
- * - Back to timegm() using GnuPG's replacement if necessary.
- * Using mktime() and localtime() could add a on hour offset if
- * the randomize factor was big enough to lead to a summer/wintertime
- * switch.
- *
- * - Removed now-useless Privoxy 3.0.3 compatibility glue.
- *
- * - Moved randomization code into pick_from_range().
- *
- * - Changed parse_header_time definition.
- * time_t isn't guaranteed to be signed and
- * if it isn't, -1 isn't available as error code.
- * Changed some variable types in client_if_modified_since()
- * because of the same reason.
- *
- * Revision 1.39 2006/07/18 14:48:46 david__schmidt
- * Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
- * with what was really the latest development (the v_3_0_branch branch)
- *
- * Revision 1.37.2.4 2003/12/01 14:45:14 oes
- * Fixed two more problems with wildcarding in simplematch()
- *
- * Revision 1.37.2.3 2003/11/20 11:39:24 oes
- * Bugfix: The "?" wildcard for domain names had never been implemented. Ooops\!
- *
- * Revision 1.37.2.2 2002/11/12 14:28:18 oes
- * Proper backtracking in simplematch; fixes bug #632888
- *
- * Revision 1.37.2.1 2002/09/25 12:58:51 oes
- * Made strcmpic and strncmpic safe against NULL arguments
- * (which are now treated as empty strings).
- *
- * Revision 1.37 2002/04/26 18:29:43 jongfoster
- * Fixing this Visual C++ warning:
- * miscutil.c(710) : warning C4090: '=' : different 'const' qualifiers
- *
- * Revision 1.36 2002/04/26 12:55:38 oes
- * New function string_toupper
- *
- * Revision 1.35 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.34 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.33 2002/03/07 03:46:53 oes
- * Fixed compiler warnings etc
- *
- * Revision 1.32 2002/03/06 23:02:57 jongfoster
- * Removing tabs
- *
- * Revision 1.31 2002/03/05 04:52:42 oes
- * Deleted non-errlog debugging code
- *
- * Revision 1.30 2002/03/04 18:27:42 oes
- * - Deleted deletePidFile
- * - Made write_pid_file use the --pidfile option value
- * (or no PID file, if the option was absent)
- * - Played styleguide police
- *
- * Revision 1.29 2002/03/04 02:08:02 david__schmidt
- * Enable web editing of actions file on OS/2 (it had been broken all this time!)
- *
- * Revision 1.28 2002/03/03 09:18:03 joergs
- * Made jumbjuster work on AmigaOS again.
- *
- * Revision 1.27 2002/01/21 00:52:32 jongfoster
- * Adding string_join()
- *
- * Revision 1.26 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.25 2001/11/13 00:16:38 jongfoster
- * Replacing references to malloc.h with the standard stdlib.h
- * (See ANSI or K&R 2nd Ed)
- *
- * Revision 1.24 2001/11/05 21:41:43 steudten
- * Add changes to be a real daemon just for unix os.
- * (change cwd to /, detach from controlling tty, set
- * process group and session leader to the own process.
- * Add DBG() Macro.
- * Add some fatal-error log message for failed malloc().
- * Add '-d' if compiled with 'configure --with-debug' to
- * enable debug output.
- *
- * Revision 1.23 2001/10/29 03:48:10 david__schmidt
- * OS/2 native needed a snprintf() routine. Added one to miscutil, brackedted
- * by and __OS2__ ifdef.
- *
- * Revision 1.22 2001/10/26 17:39:38 oes
- * Moved ijb_isspace and ijb_tolower to project.h
- *
- * Revision 1.21 2001/10/23 21:27:50 jongfoster
- * Standardising error codes in string_append
- * make_path() no longer adds '\\' if the dir already ends in '\\' (this
- * is just copying a UNIX-specific fix to the Windows-specific part)
- *
- * Revision 1.20 2001/10/22 15:33:56 david__schmidt
- * Special-cased OS/2 out of the Netscape-abort-on-404-in-js problem in
- * filters.c. Added a FIXME in front of the offending code. I'll gladly
- * put in a better/more robust fix for all parties if one is presented...
- * It seems that just returning 200 instead of 404 would pretty much fix
- * it for everyone, but I don't know all the history of the problem.
- *
- * Revision 1.19 2001/10/14 22:02:57 jongfoster
- * New function string_append() which is like strsav(), but running
- * out of memory isn't automatically FATAL.
- *
- * Revision 1.18 2001/09/20 13:33:43 steudten
- *
- * change long to int as return value in hash_string(). Remember the wraparound
- * for int = long = sizeof(4) - thats maybe not what we want.
- *
- * Revision 1.17 2001/09/13 20:51:29 jongfoster
- * Fixing potential problems with characters >=128 in simplematch()
- * This was also a compiler warning.
- *
- * Revision 1.16 2001/09/10 10:56:59 oes
- * Silenced compiler warnings
- *
- * Revision 1.15 2001/07/13 14:02:24 oes
- * Removed vim-settings
- *
- * Revision 1.14 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.13 2001/06/29 13:32:14 oes
- * Removed logentry from cancelled commit
- *
- * Revision 1.12 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.11 2001/06/07 23:09:19 jongfoster
- * Cosmetic indentation changes.
- *
- * Revision 1.10 2001/06/07 14:51:38 joergs
- * make_path() no longer adds '/' if the dir already ends in '/'.
- *
- * Revision 1.9 2001/06/07 14:43:17 swa
- * slight mistake in make_path, unix path style is /.
- *
- * Revision 1.8 2001/06/05 22:32:01 jongfoster
- * New function make_path() to splice directory and file names together.
- *
- * Revision 1.7 2001/06/03 19:12:30 oes
- * introduced bindup()
- *
- * Revision 1.6 2001/06/01 18:14:49 jongfoster
- * Changing the calls to strerr() to check HAVE_STRERR (which is defined
- * in config.h if appropriate) rather than the NO_STRERR macro.
- *
- * Revision 1.5 2001/06/01 10:31:51 oes
- * Added character class matching to trivimatch; renamed to simplematch
- *
- * Revision 1.4 2001/05/31 17:32:31 oes
- *
- * - Enhanced domain part globbing with infix and prefix asterisk
- * matching and optional unanchored operation
- *
- * Revision 1.3 2001/05/29 23:10:09 oes
- *
- *
- * - Introduced chomp()
- * - Moved strsav() from showargs to miscutil
- *
- * Revision 1.2 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.1.1.1 2001/05/15 13:59:00 oes
- * Initial import of version 2.9.3 source tree
- *
- *
*********************************************************************/
-\f
+
#include "config.h"
#include <ctype.h>
#include <assert.h>
-#ifndef HAVE_TIMEGM
+#if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
#include <time.h>
-#endif /* #ifndef HAVE_TIMEGM */
+#endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
#include "project.h"
#include "miscutil.h"
for ( ; *s; ++s )
{
- h = 5 * h + *s;
+ h = 5 * h + (unsigned int)*s;
}
return (h);
}
-#ifdef __MINGW32__
-/*********************************************************************
- *
- * Function : strdup
- *
- * 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.
- *
- * Parameters :
- * 1 : s = string to duplicate
- *
- * Returns : Pointer to newly malloc'ed copy of the string.
- *
- *********************************************************************/
-char *strdup( const char *s )
-{
- char * result = (char *)malloc( strlen(s)+1 );
-
- if (result != NULL)
- {
- strcpy( result, s );
- }
-
- return( result );
-}
-
-#endif /* def __MINGW32__ */
-
-
-
-/*********************************************************************
- *
- * Function : safe_strerror
- *
- * Description : Variant of the library routine strerror() which will
- * work on systems without the library routine, and
- * which should never return NULL.
- *
- * Parameters :
- * 1 : err = the `errno' of the last operation.
- *
- * Returns : An "English" string of the last `errno'. Allocated
- * with strdup(), so caller frees. May be NULL if the
- * system is out of memory.
- *
- *********************************************************************/
-char *safe_strerror(int err)
-{
- char *s = NULL;
- char buf[BUFFER_SIZE];
-
-
-#ifdef HAVE_STRERROR
- s = strerror(err);
-#endif /* HAVE_STRERROR */
-
- if (s == NULL)
- {
- sprintf(buf, "(errno = %d)", err);
- s = buf;
- }
-
- return(strdup(s));
-
-}
-
-
/*********************************************************************
*
* Function : strcmpic
*
* 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
*********************************************************************/
int strncmpic(const char *s1, const char *s2, size_t n)
{
- if (n <= 0) return(0);
+ if (n <= (size_t)0) return(0);
if (!s1) s1 = "";
if (!s2) s2 = "";
break;
}
- if (--n <= 0) break;
+ if (--n <= (size_t)0) break;
s1++, s2++;
}
}
-/*********************************************************************
- *
- * Function : strsav
- *
- * Description : Reallocate "old" and append text to it. This makes
- * it easier to append to malloc'd strings.
- * Running out of memory is a FATAL error.
- *
- * Parameters :
- * 1 : old = Old text that is to be extended. Will be
- * free()d by this routine. May be NULL.
- * 2 : text_to_append = Text to be appended to old.
- * May be NULL.
- *
- * Returns : Pointer to newly malloc'ed appended string.
- * If there is no text to append, return old. Caller
- * must free().
- *
- *********************************************************************/
-char *strsav(char *old, const char *text_to_append)
-{
- size_t old_len, new_len = 0;
- char *p;
-
- if ((text_to_append == NULL) || (*text_to_append == '\0'))
- {
- return(old);
- }
-
- if (NULL == old)
- {
- if ((p = strdup(text_to_append)) == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "strdup() failed!");
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
- return p;
- }
-
- old_len = strlen(old);
- new_len = old_len + strlen(text_to_append) + 1;
-
- if ((p = realloc(old, new_len)) == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "realloc(%d) bytes failed!", new_len);
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
-
- strcpy(p + old_len, text_to_append);
- return(p);
-}
-
-
/*********************************************************************
*
* Function : string_append
{
size_t old_len;
char *new_string;
+ size_t new_size;
assert(target_string);
assert(text_to_append);
old_len = strlen(*target_string);
- if (NULL == (new_string = realloc(*target_string,
- strlen(text_to_append) + old_len + 1)))
+ new_size = strlen(text_to_append) + old_len + 1;
+
+ if (NULL == (new_string = realloc(*target_string, new_size)))
{
free(*target_string);
return JB_ERR_MEMORY;
}
- strcpy(new_string + old_len, text_to_append);
+ strlcpy(new_string + old_len, text_to_append, new_size - old_len);
*target_string = new_string;
return JB_ERR_OK;
err = string_append(target_string, text_to_append);
- free(text_to_append);
+ freez(text_to_append);
return err;
}
while (*q != '\0')
{
- *p++ = toupper((int) *q++);
+ *p++ = (char)toupper((int) *q++);
}
return result;
}
-/*********************************************************************
- *
- * Function : simplematch
- *
- * Description : String matching, with a (greedy) '*' wildcard that
- * stands for zero or more arbitrary characters and
- * character classes in [], which take both enumerations
- * and ranges.
- *
- * Parameters :
- * 1 : pattern = pattern for matching
- * 2 : text = text to be matched
- *
- * Returns : 0 if match, else nonzero
- *
- *********************************************************************/
-int simplematch(char *pattern, char *text)
-{
- unsigned char *pat = (unsigned char *) pattern;
- unsigned char *txt = (unsigned char *) text;
- unsigned char *fallback = pat;
- int wildcard = 0;
-
- unsigned char lastchar = 'a';
- unsigned i;
- unsigned char charmap[32];
-
- while (*txt)
- {
-
- /* EOF pattern but !EOF text? */
- if (*pat == '\0')
- {
- if (wildcard)
- {
- pat = fallback;
- }
- else
- {
- return 1;
- }
- }
-
- /* '*' in the pattern? */
- if (*pat == '*')
- {
-
- /* The pattern ends afterwards? Speed up the return. */
- if (*++pat == '\0')
- {
- return 0;
- }
-
- /* Else, set wildcard mode and remember position after '*' */
- wildcard = 1;
- fallback = pat;
- }
-
- /* Character range specification? */
- if (*pat == '[')
- {
- memset(charmap, '\0', sizeof(charmap));
-
- while (*++pat != ']')
- {
- if (!*pat)
- {
- return 1;
- }
- else if (*pat == '-')
- {
- if ((*++pat == ']') || *pat == '\0')
- {
- return(1);
- }
- for(i = lastchar; i <= *pat; i++)
- {
- charmap[i / 8] |= (1 << (i % 8));
- }
- }
- else
- {
- charmap[*pat / 8] |= (1 << (*pat % 8));
- lastchar = *pat;
- }
- }
- } /* -END- if Character range specification */
-
-
- /*
- * Char match, or char range match?
- */
- if ( (*pat == *txt)
- || (*pat == '?')
- || ((*pat == ']') && (charmap[*txt / 8] & (1 << (*txt % 8)))) )
- {
- /*
- * Sucess: Go ahead
- */
- pat++;
- }
- else if (!wildcard)
- {
- /*
- * No match && no wildcard: No luck
- */
- return 1;
- }
- else if (pat != fallback)
- {
- /*
- * Increment text pointer if in char range matching
- */
- if (*pat == ']')
- {
- txt++;
- }
- /*
- * Wildcard mode && nonmatch beyond fallback: Rewind pattern
- */
- pat = fallback;
- /*
- * Restart matching from current text pointer
- */
- continue;
- }
- txt++;
- }
-
- /* Cut off extra '*'s */
- if(*pat == '*') pat++;
-
- /* If this is the pattern's end, fine! */
- return(*pat);
-
-}
-
-
/*********************************************************************
*
* Function : bindup
strncpy(path,dir,512);
}
path[511]=0;
- } else {
+ }
+ else
+ {
path[0]=0;
}
if(AddPart(path,file,512))
{
return strdup(path);
- } else {
+ }
+ else
+ {
return NULL;
}
#else /* ndef AMIGA */
else
{
char * path;
+ size_t path_size = strlen(dir) + strlen(file) + 2; /* +2 for trailing (back)slash and \0 */
#if defined(unix)
if ( *dir != '/' && basedir && *basedir )
{
- path = malloc( strlen( basedir ) + strlen(dir) + strlen(file) + 3);
+ /*
+ * 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!");
- strcpy(path, basedir);
- strcat(path, "/");
- strcat(path, dir);
+ strlcpy(path, basedir, path_size);
+ strlcat(path, "/", path_size);
+ strlcat(path, dir, path_size);
}
else
+#endif /* defined unix */
{
- path = malloc(strlen(dir) + strlen(file) + 2);
+ path = malloc(path_size);
if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
- strcpy(path, dir);
+ strlcpy(path, dir, path_size);
}
-#else
-
- path = malloc(strlen(dir) + strlen(file) + 2);
- if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
- strcpy(path, dir);
-
-#endif /* defined unix */
+ assert(NULL != path);
#if defined(_WIN32) || defined(__OS2__)
if(path[strlen(path)-1] != '\\')
{
- strcat(path, "\\");
+ strlcat(path, "\\", path_size);
}
#else /* ifndef _WIN32 || __OS2__ */
if(path[strlen(path)-1] != '/')
{
- strcat(path, "/");
+ strlcat(path, "/", path_size);
}
#endif /* ifndef _WIN32 || __OS2__ */
- strcat(path, file);
+ strlcat(path, file, path_size);
return path;
}
* Returns : Picked number.
*
*********************************************************************/
-
long int pick_from_range(long int range)
{
long int number;
-#ifndef HAVE_RANDOM
- unsigned int weak_seed;
+#ifdef _WIN32
+ static unsigned long seed = 0;
+#endif /* def _WIN32 */
+
+ assert(range != 0);
+ assert(range > 0);
- weak_seed = (unsigned int)((unsigned int)time(NULL) | (unsigned int)range);
- srand(weak_seed);
+ if (range <= 0) return 0;
+
+#ifdef HAVE_RANDOM
+ number = random() % range + 1;
+#elif defined(MUTEX_LOCKS_AVAILABLE)
+ privoxy_mutex_lock(&rand_mutex);
+#ifdef _WIN32
+ if (!seed)
+ {
+ seed = (unsigned long)(GetCurrentThreadId()+GetTickCount());
+ }
+ srand(seed);
+ seed = (unsigned long)((rand() << 16) + rand());
+#endif /* def _WIN32 */
+ number = (unsigned long)((rand() << 16) + (rand())) % (unsigned long)(range + 1);
+ privoxy_mutex_unlock(&rand_mutex);
+#else
/*
- * Some rand implementations aren't that random and return mostly
- * lower numbers. Low entropy doesn't matter for the header times,
- * but higher "random" factors are prefered.
+ * XXX: Which platforms reach this and are there
+ * better options than just using rand() and hoping
+ * that it's safe?
*/
- number = (rand() * 12345) % (long int)(range + 1);
- /* Overflows don't matter either, positive numbers do. */
- if(number<0)
+ log_error(LOG_LEVEL_INFO, "No thread-safe PRNG available? Header time randomization "
+ "might cause crashes, predictable results or even combine these fine options.");
+ number = rand() % (long int)(range + 1);
+
+#endif /* (def HAVE_RANDOM) */
+
+ return number;
+}
+
+
+#ifdef USE_PRIVOXY_STRLCPY
+/*********************************************************************
+ *
+ * Function : privoxy_strlcpy
+ *
+ * Description : strlcpy(3) look-alike for those without decent libc.
+ *
+ * Parameters :
+ * 1 : destination: buffer to copy into.
+ * 2 : source: String to copy.
+ * 3 : size: Size of destination buffer.
+ *
+ * Returns : The length of the string that privoxy_strlcpy() tried to create.
+ *
+ *********************************************************************/
+size_t privoxy_strlcpy(char *destination, const char *source, const size_t size)
+{
+ if (0 < size)
{
- number*= -1;
+ snprintf(destination, size, "%s", source);
+ /*
+ * Platforms that lack strlcpy() also tend to have
+ * a broken snprintf implementation that doesn't
+ * guarantee nul termination.
+ *
+ * XXX: the configure script should detect and reject those.
+ */
+ destination[size-1] = '\0';
}
-#else
- number = random() % range + 1;
-#endif /* (ifndef HAVE_RANDOM) */
- return (number);
+ return strlen(source);
}
+#endif /* def USE_PRIVOXY_STRLCPY */
-#ifndef HAVE_TIMEGM
+#ifndef HAVE_STRLCAT
+/*********************************************************************
+ *
+ * Function : privoxy_strlcat
+ *
+ * Description : strlcat(3) look-alike for those without decent libc.
+ *
+ * Parameters :
+ * 1 : destination: C string.
+ * 2 : source: String to copy.
+ * 3 : size: Size of destination buffer.
+ *
+ * Returns : The length of the string that privoxy_strlcat() tried to create.
+ *
+ *********************************************************************/
+size_t privoxy_strlcat(char *destination, const char *source, const size_t size)
+{
+ const size_t old_length = strlen(destination);
+ return old_length + strlcpy(destination + old_length, source, size - old_length);
+}
+#endif /* ndef HAVE_STRLCAT */
+
+
+#if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
/*********************************************************************
*
* Function : timegm
*
- * Description : libc replacement function for the inverse of gmtime()
+ * Description : libc replacement function for the inverse of gmtime().
* Copyright (C) 2004 Free Software Foundation, Inc.
- * Code copied from GnuPG with minor style changes.
+ *
+ * Code originally copied from GnuPG, modifications done
+ * for Privoxy: style changed, #ifdefs for _WIN32 added
+ * to have it work on mingw32.
+ *
+ * XXX: It's very unlikely to happen, but if the malloc()
+ * call fails the time zone will be permanently set to UTC.
*
* Parameters :
* 1 : tm: Broken-down time struct.
* Returns : tm converted into time_t seconds.
*
*********************************************************************/
-
time_t timegm(struct tm *tm)
{
time_t answer;
char *zone;
- zone=getenv("TZ");
+ zone = getenv("TZ");
putenv("TZ=UTC");
tzset();
- answer=mktime(tm);
- if(zone)
+ answer = mktime(tm);
+ if (zone)
{
char *old_zone;
- old_zone=malloc(3+strlen(zone)+1);
- if(old_zone)
+ old_zone = malloc(3 + strlen(zone) + 1);
+ if (old_zone)
{
- strcpy(old_zone,"TZ=");
- strcat(old_zone,zone);
+ strcpy(old_zone, "TZ=");
+ strcat(old_zone, zone);
putenv(old_zone);
+#ifdef _WIN32
+ free(old_zone);
+#endif /* def _WIN32 */
}
}
else
{
#ifdef HAVE_UNSETENV
unsetenv("TZ");
+#elif defined(_WIN32)
+ putenv("TZ=");
#else
putenv("TZ");
#endif
}
tzset();
+
return answer;
}
-#endif /* (ifndef HAVE_TIMEGM) */
+#endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
+#ifndef HAVE_SNPRINTF
/*
* What follows is a portable snprintf routine, written by Mark Martinec.
* See: http://www.ijs.si/software/snprintf/
- * Anyone who needs it can add a define for themselves... so far, only
- * OS/2 (native) lacks snprintf.
snprintf.c
- a portable implementation of snprintf,
*/
-#ifdef __OS2__
-
#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
#define PORTABLE_SNPRINTF_VERSION_MINOR 2
#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 *
return (int) str_l;
}
#endif
-#endif /* __OS2__ */
+#endif /* ndef HAVE_SNPRINTF */
/*
Local Variables:
tab-width: 3