1 /* 2 * Copyright 2001-2004 Brandon Long 3 * All Rights Reserved. 4 * 5 * ClearSilver Templating System 6 * 7 * This code is made available under the terms of the ClearSilver License. 8 * http://www.clearsilver.net/license.hdf 9 * 10 */ 11 12 #include "cs_config.h" 13 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include <string.h> 17 #include <time.h> 18 #include <limits.h> 19 #include "util/neo_misc.h" 20 #include "neo_date.h" 21 22 /* This is pretty much a HACK. Eventually, we might bring the parsing 23 * and stuff into this library (we can use the public domain source code 24 * from ftp://elsie.nci.nih.gov/pub/ as a base) 25 * 26 * For now, we just do a putenv(TZ)... which sucks, especially since 27 * many versions of putenv do a strdup... and then leak the memory the 28 * next time you putenv the same var. 29 */ 30 31 /* Since this is set to a partial filename and TZ=, it can't be bigger 32 * than this */ 33 static char TzBuf[_POSIX_PATH_MAX + 4]; 34 35 static int time_set_tz (const char *mytimezone) 36 { 37 snprintf (TzBuf, sizeof(TzBuf), "TZ=%s", mytimezone); 38 putenv(TzBuf); 39 tzset(); 40 return 0; 41 } 42 43 void neo_time_expand (const time_t tt, const char *mytimezone, struct tm *ttm) 44 { 45 const char *cur_tz = getenv("TZ"); 46 int change_back = 0; 47 if (cur_tz == NULL || strcmp(mytimezone, cur_tz)) { 48 time_set_tz (mytimezone); 49 change_back = 1; 50 } 51 localtime_r (&tt, ttm); 52 if (cur_tz && change_back) { 53 time_set_tz(cur_tz); 54 } 55 } 56 57 time_t neo_time_compact (struct tm *ttm, const char *mytimezone) 58 { 59 time_t r; 60 int save_isdst = ttm->tm_isdst; 61 62 const char *cur_tz = getenv("TZ"); 63 int change_back = 0; 64 if (cur_tz == NULL || strcmp(mytimezone, cur_tz)) { 65 time_set_tz (mytimezone); 66 change_back = 1; 67 } 68 ttm->tm_isdst = -1; 69 r = mktime(ttm); 70 ttm->tm_isdst = save_isdst; 71 if (cur_tz && change_back) { 72 time_set_tz(cur_tz); 73 } 74 return r; 75 } 76 77 /* Hefted from NCSA HTTPd src/util.c -- What a pain in the ass. */ 78 long neo_tz_offset(struct tm *ttm) { 79 /* We assume here that HAVE_TM_ZONE implies HAVE_TM_GMTOFF and 80 * HAVE_TZNAME implies HAVE_TIMEZONE since AC_STRUCT_TIMEZONE defines 81 * the former and not the latter */ 82 #if defined(HAVE_TM_ZONE) 83 return ttm->tm_gmtoff; 84 #elif defined(HAVE_TZNAME) 85 long tz; 86 #ifndef __CYGWIN__ 87 tz = - timezone; 88 #else 89 tz = - _timezone; 90 #endif 91 if(ttm->tm_isdst) 92 tz += 3600; 93 return tz; 94 #else 95 long tz; 96 struct tm loc_tm, gmt_tm; 97 time_t tt; 98 99 /* We probably shouldn't use the _r versions here since this 100 * is for older platforms... */ 101 tt = time(NULL); 102 localtime_r(&tt, &loc_tm); 103 gmtime_r(&tt, &gmt_tm); 104 105 tz = mktime(&loc_tm) - mktime(&gmt_tm); 106 return tz; 107 #endif /* GMT OFFSet Crap */ 108 } 109 110