12aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** 22aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Definitions and Implementation for <time.h>. 32aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 453e1e5c647b73e45569ed6e8b8a0a5b276aa685edarylm Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> 52aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm This program and the accompanying materials are licensed and made available under 62aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm the terms and conditions of the BSD License that accompanies this distribution. 72aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm The full text of the license may be found at 82aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm http://opensource.org/licenses/bsd-license.php. 92aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Portions derived from the NIH time zone package file, localtime.c, 142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm which contains the following notice: 152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm This file is in the public domain, so clarified as of 172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). 182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm NetBSD: localtime.c,v 1.39 2006/03/22 14:01:30 christos Exp 202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <Uefi.h> 222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <Library/UefiLib.h> 232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <Library/TimerLib.h> 242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <Library/BaseLib.h> 252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <Library/UefiRuntimeServicesTableLib.h> 262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm//#include <Library/UefiRuntimeLib.h> 272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <LibConfig.h> 292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <errno.h> 312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <limits.h> 322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <time.h> 332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <reentrant.h> 342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "tzfile.h" 352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "TimeVals.h" 362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <MainData.h> 372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include <extern.h> // Library/include/extern.h: Private to implementation 382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */ 402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm// Keep compiler quiet about casting from function to data pointers 412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#pragma warning ( disable : 4054 ) 422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined(_MSC_VER) */ 432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* ####################### Private Data ################################# */ 452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#if 0 472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic EFI_TIME TimeBuffer; 482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static UINT16 MonthOffs[12] = { 502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 00, 512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 31, 59, 90, 120, 522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 151, 181, 212, 243, 532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 273, 304, 334 542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm }; 552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static clock_t y2kOffs = 730485; 562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif 572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmconst int mon_lengths[2][MONSPERYEAR] = { 592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}; 622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmconst int year_lengths[2] = { 642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm DAYSPERNYEAR, DAYSPERLYEAR 652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}; 662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic const char *wday_name[7] = { 692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}; 712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic const char *mon_name[12] = { 732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "Jan", "Feb", "Mar", "Apr", "May", "Jun", 742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm}; 762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int gmt_is_set; 782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* ############### Implementation Functions ############################ */ 802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm// Forward reference 812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic void 822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmlocalsub(const time_t * const timep, const long offset, struct tm * const tmp); 832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmclock_t 852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm__getCPS(void) 862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return gMD->ClocksPerSecond; 882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic void 912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtimesub( 922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const time_t * const timep, 932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const long offset, 942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const struct state * const sp, 952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm struct tm * const tmp 962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ) 972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const struct lsinfo * lp; 992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t /*INTN*/ days; 1002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t /*INTN*/ rem; 1012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t /*INTN*/ y; 1022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int yleap; 1032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const int * ip; 1042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t /*INTN*/ corr; 1052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int hit; 1062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int i; 1072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm corr = 0; 1092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm hit = 0; 1102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ALL_STATE 1112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = (sp == NULL) ? 0 : sp->leapcnt; 1122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined ALL_STATE */ 1132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef ALL_STATE 1142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = sp->leapcnt; 1152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* State Farm */ 1162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (--i >= 0) { 1172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm lp = &sp->lsis[i]; 1182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (*timep >= lp->ls_trans) { 1192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (*timep == lp->ls_trans) { 1202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm hit = ((i == 0 && lp->ls_corr > 0) || 1212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm lp->ls_corr > sp->lsis[i - 1].ls_corr); 1222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (hit) 1232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (i > 0 && 1242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && 1252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1 ) 1262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm { 1272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ++hit; 1282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm --i; 1292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm corr = lp->ls_corr; 1322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm break; 1332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm days = *timep / SECSPERDAY; 1362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rem = *timep % SECSPERDAY; 1372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rem += (offset - corr); 1382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (rem < 0) { 1392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rem += SECSPERDAY; 1402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm --days; 1412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (rem >= SECSPERDAY) { 1432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rem -= SECSPERDAY; 1442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ++days; 1452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_hour = (int) (rem / SECSPERHOUR); 1472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rem = rem % SECSPERHOUR; 1482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_min = (int) (rem / SECSPERMIN); 1492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 1502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** A positive leap second requires a special 1512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** representation. This uses "... ??:59:60" et seq. 1522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 1532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; 1542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); 1552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (tmp->tm_wday < 0) 1562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_wday += DAYSPERWEEK; 1572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm y = EPOCH_YEAR; 1582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (days < 0 || days >= (LONG32) year_lengths[yleap = isleap(y)]) { 1592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t /*INTN*/ newy; 1602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm newy = (y + days / DAYSPERNYEAR); 1622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (days < 0) 1632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm --newy; 1642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm days -= (newy - y) * DAYSPERNYEAR + 1652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm LEAPS_THRU_END_OF(newy - 1) - 1662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm LEAPS_THRU_END_OF(y - 1); 1672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm y = newy; 1682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 1692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_year = (int)(y - TM_YEAR_BASE); 1702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_yday = (int) days; 1712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ip = mon_lengths[yleap]; 1722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (tmp->tm_mon = 0; days >= (LONG32) ip[tmp->tm_mon]; ++(tmp->tm_mon)) 1732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm days = days - (LONG32) ip[tmp->tm_mon]; 1742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_mday = (int) (days + 1); 1752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_isdst = 0; 1762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef TM_GMTOFF 1772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->TM_GMTOFF = offset; 1782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined TM_GMTOFF */ 1792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 1802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* ############### Time Manipulation Functions ########################## */ 1822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** 1842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 1852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdouble 1862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdifftime(time_t time1, time_t time0) 1872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 1882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return (double)(time1 - time0); 1892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 1902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* 1922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** Adapted from code provided by Robert Elz, who writes: 1932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** The "best" way to do mktime I think is based on an idea of Bob 1942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** Kridle's (so its said...) from a long time ago. 1952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** [kridle@xinet.com as of 1996-01-16.] 1962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** It does a binary search of the time_t space. Since time_t's are 1972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** just 32 bits, its a max of 32 iterations (even at 64 bits it 1982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** would still be very reasonable). 1992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm*/ 2002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef WRONG 2022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define WRONG (-1) 2032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* !defined WRONG */ 2042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* 2062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com). 2072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm*/ 2082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int 2102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmincrement_overflow(int * number, int delta) 2112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 2122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int number0; 2132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm number0 = *number; 2152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm *number += delta; 2162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return (*number < number0) != (delta < 0); 2172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 2182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int 2202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmnormalize_overflow(int * const tensptr, int * const unitsptr, const int base) 2212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 2222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int tensdelta; 2232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tensdelta = (*unitsptr >= 0) ? 2252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); 2262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm *unitsptr -= tensdelta * base; 2272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return increment_overflow(tensptr, tensdelta); 2282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 2292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic int 2312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtmcomp(const struct tm * const atmp, const struct tm * const btmp) 2322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 2332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int result; 2342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && 2362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (result = (atmp->tm_min - btmp->tm_min)) == 0) 2402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm result = atmp->tm_sec - btmp->tm_sec; 2412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return result; 2422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 2432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic time_t 2452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtime2sub( 2462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm struct tm * const tmp, 2472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm void (* const funcp)(const time_t*, long, struct tm*), 2482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const long offset, 2492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int * const okayp, 2502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const int do_norm_secs 2512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ) 2522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 2532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register const struct state * sp; 2542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int dir; 2552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int bits; 2562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int i, j ; 2572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int saved_seconds; 2582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t newt; 2592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t t; 2602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm struct tm yourtm, mytm; 2612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 2622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm *okayp = FALSE; 2632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm = *tmp; // Create a copy of tmp 2642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (do_norm_secs) { 2652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, 2662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm SECSPERMIN)) 2672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 2692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 2702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 2722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) 2742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 2762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Turn yourtm.tm_year into an actual year number for now. 2772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** It is converted back to an offset from TM_YEAR_BASE later. 2782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 2792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) 2802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (yourtm.tm_mday <= 0) { 2822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (increment_overflow(&yourtm.tm_year, -1)) 2832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = yourtm.tm_year + (1 < yourtm.tm_mon); 2852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm.tm_mday += year_lengths[isleap(i)]; 2862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 2872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (yourtm.tm_mday > DAYSPERLYEAR) { 2882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = yourtm.tm_year + (1 < yourtm.tm_mon); 2892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm.tm_mday -= year_lengths[isleap(i)]; 2902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (increment_overflow(&yourtm.tm_year, 1)) 2912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 2922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 2932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for ( ; ; ) { 2942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; 2952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (yourtm.tm_mday <= i) 2962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm break; 2972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm.tm_mday -= i; 2982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (++yourtm.tm_mon >= MONSPERYEAR) { 2992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm.tm_mon = 0; 3002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (increment_overflow(&yourtm.tm_year, 1)) 3012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 3022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) 3052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 3062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 3072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm saved_seconds = 0; 3082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { 3092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 3102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** We can't set tm_sec to 0, because that might push the 3112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** time below the minimum representable time. 3122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Set tm_sec to 59 instead. 3132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** This assumes that the minimum representable time is 3142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** not in the same minute that a leap second was deleted from, 3152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** which is a safer assumption than using 58 would be. 3162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 3172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 3182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 3192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm saved_seconds = yourtm.tm_sec; 3202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm.tm_sec = SECSPERMIN - 1; 3212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } else { 3222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm saved_seconds = yourtm.tm_sec; 3232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm yourtm.tm_sec = 0; 3242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 3262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Divide the search space in half 3272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** (this works whether time_t is signed or unsigned). 3282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 3292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm bits = TYPE_BIT(time_t) - 1; 3302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 3312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Set t to the midpoint of our binary search. 3322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** 3332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** If time_t is signed, then 0 is just above the median, 3342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** assuming two's complement arithmetic. 3352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** If time_t is unsigned, then (1 << bits) is just above the median. 3362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 3372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); 3382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for ( ; ; ) { 3392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (*funcp)(&t, offset, &mytm); // Convert t to broken-down time in mytm 3402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm dir = tmcomp(&mytm, &yourtm); // Is mytm larger, equal, or less than yourtm? 3412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (dir != 0) { // If mytm != yourtm... 3422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (bits-- < 0) // If we have exhausted all the bits.. 3432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; // Return that we failed 3442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (bits < 0) // If on the last bit... 3452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm --t; /* may be needed if new t is minimal */ 3462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else if (dir > 0) // else if mytm > yourtm... 3472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t -= ((time_t) 1) << bits; // subtract half the remaining time-space 3482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else t += ((time_t) 1) << bits; // otherwise add half the remaining time-space 3492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; // Repeat for the next half 3502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 3522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm break; 3532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 3542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Right time, wrong type. 3552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Hunt for right time, right type. 3562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** It's okay to guess wrong since the guess 3572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** gets checked. 3582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 3592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 3602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. 3612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 3622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp = (const struct state *) 3632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (((void *) funcp == (void *) localsub) ? 3642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm lclptr : gmtptr); 3652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ALL_STATE 3662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp == NULL) 3672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 3682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined ALL_STATE */ 3692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (i = sp->typecnt - 1; i >= 0; --i) { 3702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 3712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; 3722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (j = sp->typecnt - 1; j >= 0; --j) { 3732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 3742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; 3752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm newt = t + sp->ttis[j].tt_gmtoff - 3762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp->ttis[i].tt_gmtoff; 3772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (*funcp)(&newt, offset, &mytm); 3782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (tmcomp(&mytm, &yourtm) != 0) 3792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; 3802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (mytm.tm_isdst != yourtm.tm_isdst) 3812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; 3822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 3832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** We have a match. 3842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 3852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t = newt; 3862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm goto label; 3872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 3902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 3912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm label: 3922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm newt = t + saved_seconds; 3932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if ((newt < t) != (saved_seconds < 0)) 3942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 3952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t = newt; 3962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (*funcp)(&t, offset, tmp); 3972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm *okayp = TRUE; 3982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return t; 3992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 4002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 401d7ce700605e1af0e455e31ec11f19ff21d26b525darylmtime_t 4022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtime2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*), 4032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const long offset, int * const okayp) 4042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 4052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t t; 4062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 4072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 4082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** First try without normalization of seconds 4092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** (in case tm_sec contains a value associated with a leap second). 4102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** If that fails, try with normalization of seconds. 4112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 4122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t = time2sub(tmp, funcp, offset, okayp, FALSE); 4132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE); 4142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 4152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 4162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic time_t 4172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtime1( 4182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm struct tm * const tmp, 4192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm void (* const funcp)(const time_t *, long, struct tm *), 4202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const long offset 4212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ) 4222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 4232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register time_t t; 4242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register const struct state * sp; 4252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int samei, otheri; 4262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int sameind, otherind; 4272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int i; 4282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int nseen; 4292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int seen[TZ_MAX_TYPES]; 4302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int types[TZ_MAX_TYPES]; 4312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int okay; 4322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 4332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (tmp->tm_isdst > 1) 4342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_isdst = 1; 4352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t = time2(tmp, funcp, offset, &okay); 4362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef PCTS 4372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 4382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** PCTS code courtesy Grant Sullivan (grant@osf.org). 4392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 4402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (okay) 4412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return t; 4422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (tmp->tm_isdst < 0) 4432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_isdst = 0; /* reset to std and try again */ 4442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined PCTS */ 4452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef PCTS 4462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (okay || tmp->tm_isdst < 0) 4472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return t; 4482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* !defined PCTS */ 4492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 4502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** We're supposed to assume that somebody took a time of one type 4512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** and did some math on it that yielded a "struct tm" that's bad. 4522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** We try to divine the type they started from and adjust to the 4532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** type they need. 4542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 4552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 4562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. 4572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 4582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp = (const struct state *) (((void *) funcp == (void *) localsub) ? 4592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm lclptr : gmtptr); 4602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ALL_STATE 4612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp == NULL) 4622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 4632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined ALL_STATE */ 4642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (i = 0; i < sp->typecnt; ++i) 4652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm seen[i] = FALSE; 4662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm nseen = 0; 4672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (i = sp->timecnt - 1; i >= 0; --i) 4682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (!seen[sp->types[i]]) { 4692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm seen[sp->types[i]] = TRUE; 4702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm types[nseen++] = sp->types[i]; 4712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 4722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (sameind = 0; sameind < nseen; ++sameind) { 4732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm samei = types[sameind]; 4742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 4752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; 4762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (otherind = 0; otherind < nseen; ++otherind) { 4772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm otheri = types[otherind]; 4782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 4792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm continue; 4802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_sec += (int)(sp->ttis[otheri].tt_gmtoff - 4812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp->ttis[samei].tt_gmtoff); 4822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_isdst = !tmp->tm_isdst; 4832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm t = time2(tmp, funcp, offset, &okay); 4842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (okay) 4852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return t; 4862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_sec -= (int)(sp->ttis[otheri].tt_gmtoff - 4872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp->ttis[samei].tt_gmtoff); 4882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_isdst = !tmp->tm_isdst; 4892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 4902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 4912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return WRONG; 4922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 4932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 4942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** The mktime function converts the broken-down time, expressed as local time, 4952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm in the structure pointed to by timeptr into a calendar time value with the 4962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm same encoding as that of the values returned by the time function. The 4972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm original values of the tm_wday and tm_yday components of the structure are 4982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ignored, and the original values of the other components are not restricted 4992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm to the ranges indicated above. Thus, a positive or zero value for tm_isdst 5002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm causes the mktime function to presume initially that Daylight Saving Time, 5012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm respectively, is or is not in effect for the specified time. A negative 5022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm value causes it to attempt to determine whether Daylight Saving Time is in 5032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm effect for the specified time. On successful completion, the values of the 5042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tm_wday and tm_yday components of the structure are set appropriately, and 5052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm the other components are set to represent the specified calendar time, but 5062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm with their values forced to the ranges indicated above; the final value of 5072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tm_mday is not set until tm_mon and tm_year are determined. 5082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm @return The mktime function returns the specified calendar time encoded 5102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm as a value of type time_t. If the calendar time cannot be 5112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm represented, the function returns the value (time_t)(-1). 5122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 5132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtime_t 5142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmmktime(struct tm *timeptr) 5152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 5162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* From NetBSD */ 5172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t result; 5182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rwlock_wrlock(&lcl_lock); 5202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tzset(); 5212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm result = time1(timeptr, &localsub, 0L); 5222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm rwlock_unlock(&lcl_lock); 5232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return (result); 5242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 5252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** The time function determines the current calendar time. The encoding of 5272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm the value is unspecified. 5282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 529d7ce700605e1af0e455e31ec11f19ff21d26b525darylm @return The time function returns the implementation's best approximation 5302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm to the current calendar time. The value (time_t)(-1) is returned 5312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if the calendar time is not available. If timer is not a null 5322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm pointer, the return value is also assigned to the object it 5332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm points to. 5342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 5352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtime_t 5362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtime(time_t *timer) 5372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 5382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm time_t CalTime; 5392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm EFI_STATUS Status; 5402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm EFI_TIME *ET; 5412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm struct tm *BT; 5422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ET = &gMD->TimeBuffer; 5442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm BT = &gMD->BDTime; 5452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm // Get EFI Time 5472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Status = gRT->GetTime( ET, NULL); 5482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm// Status = EfiGetTime( ET, NULL); 5492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm EFIerrno = Status; 5502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if( Status != RETURN_SUCCESS) { 5512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return (time_t)-1; 5522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 5532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm // Convert EFI time to broken-down time. 5552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Efi2Tm( ET, BT); 5562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm // Convert to time_t 5582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm CalTime = mktime(&gMD->BDTime); 5592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if( timer != NULL) { 5612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm *timer = CalTime; 5622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 5632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return CalTime; // Return calendar time in microseconds 5642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 5652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5668aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm/** The clock function determines the processor time used. 5678aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm 5688aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm @return The clock function returns the implementation's best 5698aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm approximation to the processor time used by the program since the 5708aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm beginning of an implementation-defined era related only to the 5718aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm program invocation. To determine the time in seconds, the value 5728aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm returned by the clock function should be divided by the value of 5738aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm the macro CLOCKS_PER_SEC. If the processor time used is not 5748aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm available or its value cannot be represented, the function 5758aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm returns the value (clock_t)(-1). 5768aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm**/ 5778aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylmclock_t 5788aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylmclock(void) 5798aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm{ 5808aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm clock_t retval; 5818aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm time_t temp; 5828aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm 5838aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm temp = time(NULL); 5848aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm retval = ((clock_t)((UINT32)temp)) - gMD->AppStartTime; 5858aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm return retval; 5868aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm} 5878aa163da5ac7bf40d1a3b0612a46504dc56d16a2darylm 5882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* ################# Time Conversion Functions ########################## */ 5892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* 5902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Except for the strftime function, these functions each return a pointer to 5912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm one of two types of static objects: a broken-down time structure or an 5922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm array of char. Execution of any of the functions that return a pointer to 5932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm one of these object types may overwrite the information in any object of 5942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm the same type pointed to by the value returned from any previous call to 5952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm any of them. The implementation shall behave as if no other library 5962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm functions call these functions. 5972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm*/ 5982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 5992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** The asctime function converts the broken-down time in the structure pointed 6002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm to by timeptr into a string in the form 6012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Sun Sep 16 01:03:52 1973\n\0 6022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm using the equivalent of the following algorithm. 6032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 6042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm char *asctime(const struct tm *timeptr) 6052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm { 6062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static const char wday_name[7][3] = { 6072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 6082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm }; 6092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static const char mon_name[12][3] = { 6102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "Jan", "Feb", "Mar", "Apr", "May", "Jun", 6112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 6122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm }; 6132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static char result[26]; 6142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", 6152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm wday_name[timeptr->tm_wday], 6162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm mon_name[timeptr->tm_mon], 6172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm timeptr->tm_mday, timeptr->tm_hour, 6182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm timeptr->tm_min, timeptr->tm_sec, 6192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 1900 + timeptr->tm_year); 6202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return result; 6212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 6222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm @return The asctime function returns a pointer to the string. 6232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 6242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmchar * 6252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmasctime(const struct tm *timeptr) 6262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 6272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register const char * wn; 6282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register const char * mn; 6292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 6302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) 6312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm wn = "???"; 6322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else wn = wday_name[timeptr->tm_wday]; 6332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) 6342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm mn = "???"; 6352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else mn = mon_name[timeptr->tm_mon]; 6362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 6372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** The X3J11-suggested format is 6382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" 6392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Since the .2 in 02.2d is ignored, we drop it. 6402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 6412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm (void)snprintf(gMD->ASasctime, 6422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sizeof (char[ASCTIME_BUFLEN]), 6432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm "%.3s %.3s%3d %02d:%02d:%02d %d\r\n", // explicit CRLF for EFI 6442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm wn, mn, 6452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm timeptr->tm_mday, timeptr->tm_hour, 6462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm timeptr->tm_min, timeptr->tm_sec, 6472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm TM_YEAR_BASE + timeptr->tm_year); 6482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return gMD->ASasctime; 6492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 6502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 6512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** 6522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 6532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmchar * 6542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmctime(const time_t *timer) 6552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 6562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return asctime(localtime(timer)); 6572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 6582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 6592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* 6602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm** gmtsub is to gmtime as localsub is to localtime. 6612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm*/ 662d7ce700605e1af0e455e31ec11f19ff21d26b525darylmvoid 6632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmgmtsub( 6642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const time_t * const timep, 6652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const long offset, 6662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm struct tm * const tmp 6672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ) 6682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 6692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef _REENTRANT 6702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static mutex_t gmt_mutex = MUTEX_INITIALIZER; 6712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif 6722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 6732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm mutex_lock(&gmt_mutex); 6742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (!gmt_is_set) { 6752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm gmt_is_set = TRUE; 6762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ALL_STATE 6772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm gmtptr = (struct state *) malloc(sizeof *gmtptr); 6782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (gmtptr != NULL) 6792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined ALL_STATE */ 6802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm gmtload(gmtptr); 6812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 6822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm mutex_unlock(&gmt_mutex); 6832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm timesub(timep, offset, gmtptr, tmp); 6842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef TM_ZONE 6852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 6862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** Could get fancy here and deliver something such as 6872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, 6882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** but this is no time for a treasure hunt. 6892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 6902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (offset != 0) 6912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->TM_ZONE = (__aconst char *)__UNCONST(wildabbr); 6922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else { 6932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ALL_STATE 6942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (gmtptr == NULL) 6952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->TM_ZONE = (__aconst char *)__UNCONST(gmt); 6962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm else tmp->TM_ZONE = gmtptr->chars; 6972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined ALL_STATE */ 6982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef ALL_STATE 6992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->TM_ZONE = gmtptr->chars; 7002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* State Farm */ 7012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 7022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined TM_ZONE */ 7032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 7042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 7052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** 7062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 7072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstruct tm * 7082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmgmtime(const time_t *timer) 7092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 7102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm gmtsub(timer, 0L, &gMD->BDTime); 7112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return &gMD->BDTime; 7122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 7132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 7142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic void 7152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmlocalsub(const time_t * const timep, const long offset, struct tm * const tmp) 7162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 7172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register struct state * sp; 7182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register const struct ttinfo * ttisp; 7192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm register int i; 7202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm const time_t t = *timep; 7212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 7222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm sp = lclptr; 7232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ALL_STATE 7242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp == NULL) { 7252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm gmtsub(timep, offset, tmp); 7262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return; 7272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 7282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined ALL_STATE */ 7292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (sp->timecnt == 0 || t < sp->ats[0]) { 7302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = 0; 7312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm while (sp->ttis[i].tt_isdst) 7322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (++i >= sp->typecnt) { 7332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = 0; 7342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm break; 7352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 7362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } else { 7372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm for (i = 1; i < sp->timecnt; ++i) 7382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm if (t < sp->ats[i]) 7392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm break; 7402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm i = sp->types[i - 1]; 7412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm } 7422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ttisp = &sp->ttis[i]; 7432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm /* 7442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** To get (wrong) behavior that's compatible with System V Release 2.0 7452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** you'd replace the statement below with 7462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** t += ttisp->tt_gmtoff; 7472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ** timesub(&t, 0L, sp, tmp); 7482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm */ 7492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm timesub(&t, ttisp->tt_gmtoff, sp, tmp); 7502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->tm_isdst = ttisp->tt_isdst; 7512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; 7522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef TM_ZONE 7532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; 7542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* defined TM_ZONE */ 7552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 7562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm 7572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/** 7582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm**/ 7592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstruct tm * 7602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmlocaltime(const time_t *timer) 7612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{ 7622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm tzset(); 7632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm localsub(timer, 0L, &gMD->BDTime); 7642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm return &gMD->BDTime; 7652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm} 766