1139738Simp/*- 283364Sdfr * Copyright (c) 1999, 2000 383364Sdfr * Intel Corporation. 483364Sdfr * All rights reserved. 583364Sdfr * 683364Sdfr * Redistribution and use in source and binary forms, with or without 783364Sdfr * modification, are permitted provided that the following conditions 883364Sdfr * are met: 983364Sdfr * 1083364Sdfr * 1. Redistributions of source code must retain the above copyright 1183364Sdfr * notice, this list of conditions and the following disclaimer. 1283364Sdfr * 1383364Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1483364Sdfr * notice, this list of conditions and the following disclaimer in the 1583364Sdfr * documentation and/or other materials provided with the distribution. 1683364Sdfr * 1783364Sdfr * 3. All advertising materials mentioning features or use of this software 1883364Sdfr * must display the following acknowledgement: 1983364Sdfr * 2083364Sdfr * This product includes software developed by Intel Corporation and 2183364Sdfr * its contributors. 2283364Sdfr * 2383364Sdfr * 4. Neither the name of Intel Corporation or its contributors may be 2483364Sdfr * used to endorse or promote products derived from this software 2583364Sdfr * without specific prior written permission. 2683364Sdfr * 2783364Sdfr * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 2883364Sdfr * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2983364Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3083364Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 3183364Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3283364Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3383364Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3483364Sdfr * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3583364Sdfr * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3683364Sdfr * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3783364Sdfr * THE POSSIBILITY OF SUCH DAMAGE. 3883364Sdfr */ 3983364Sdfr 40113038Sobrien#include <sys/cdefs.h> 41113038Sobrien__FBSDID("$FreeBSD$"); 4283364Sdfr 4383364Sdfr#include <time.h> 4483364Sdfr#include <sys/time.h> 4583666Sdfr#include <stand.h> 4683364Sdfr 4783666Sdfr#include "libski.h" 4883666Sdfr 4983364Sdfr/* 5083364Sdfr// Accurate only for the past couple of centuries; 5183364Sdfr// that will probably do. 5283364Sdfr// 5383364Sdfr// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) 5483364Sdfr*/ 5583364Sdfr 5683364Sdfr#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) 5783364Sdfr#define SECSPERHOUR ( 60*60 ) 5883364Sdfr#define SECSPERDAY (24 * SECSPERHOUR) 5983364Sdfr 6083666Sdfrstruct ssc_time { 6183666Sdfr int Year; 6283666Sdfr int Month; 6383666Sdfr int Day; 6483666Sdfr int Hour; 6583666Sdfr int Minute; 6683666Sdfr int Second; 6783666Sdfr int Msec; 6883666Sdfr int Wday; 6983666Sdfr}; 7083364Sdfr 7183364Sdfrtime_t 7283666SdfrEfiTimeToUnixTime(struct ssc_time *ETime) 7383666Sdfr{ 7483666Sdfr /* 7583666Sdfr // These arrays give the cumulative number of days up to the first of the 7683666Sdfr // month number used as the index (1 -> 12) for regular and leap years. 7783666Sdfr // The value at index 13 is for the whole year. 7883666Sdfr */ 7983666Sdfr static time_t CumulativeDays[2][14] = { 8083666Sdfr {0, 8183666Sdfr 0, 8283666Sdfr 31, 8383666Sdfr 31 + 28, 8483666Sdfr 31 + 28 + 31, 8583666Sdfr 31 + 28 + 31 + 30, 8683666Sdfr 31 + 28 + 31 + 30 + 31, 8783666Sdfr 31 + 28 + 31 + 30 + 31 + 30, 8883666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31, 8983666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 9083666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 9183666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 9283666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 9383666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, 9483666Sdfr {0, 9583666Sdfr 0, 9683666Sdfr 31, 9783666Sdfr 31 + 29, 9883666Sdfr 31 + 29 + 31, 9983666Sdfr 31 + 29 + 31 + 30, 10083666Sdfr 31 + 29 + 31 + 30 + 31, 10183666Sdfr 31 + 29 + 31 + 30 + 31 + 30, 10283666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31, 10383666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, 10483666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 10583666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 10683666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 10783666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; 10883666Sdfr 10983666Sdfr time_t UTime; 11083666Sdfr int Year; 11183666Sdfr 11283666Sdfr ETime->Year += 1900; 11383666Sdfr 11483666Sdfr /* 11583666Sdfr // Do a santity check 11683666Sdfr */ 11783666Sdfr if ( ETime->Year < 1998 || ETime->Year > 2099 || 11883666Sdfr ETime->Month == 0 || ETime->Month > 12 || 11983666Sdfr ETime->Day == 0 || ETime->Month > 31 || 12083666Sdfr ETime->Hour > 23 || 12183666Sdfr ETime->Minute > 59 || 12283666Sdfr ETime->Second > 59 ) { 12383666Sdfr return (0); 12483666Sdfr } 12583666Sdfr 12683666Sdfr /* 12783666Sdfr // Years 12883666Sdfr */ 12983666Sdfr UTime = 0; 13083666Sdfr for (Year = 1970; Year != ETime->Year; ++Year) { 13183666Sdfr UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); 13283666Sdfr } 13383666Sdfr 13483666Sdfr /* 13583666Sdfr // UTime should now be set to 00:00:00 on Jan 1 of the file's year. 13683666Sdfr // 13783666Sdfr // Months 13883666Sdfr */ 13983666Sdfr UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); 14083666Sdfr 14183666Sdfr /* 14283666Sdfr // UTime should now be set to 00:00:00 on the first of the file's month and year 14383666Sdfr // 14483666Sdfr // Days -- Don't count the file's day 14583666Sdfr */ 14683666Sdfr UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); 14783666Sdfr 14883666Sdfr /* 14983666Sdfr // Hours 15083666Sdfr */ 15183666Sdfr UTime += (ETime->Hour * SECSPERHOUR); 15283666Sdfr 15383666Sdfr /* 15483666Sdfr // Minutes 15583666Sdfr */ 15683666Sdfr UTime += (ETime->Minute * 60); 15783666Sdfr 15883666Sdfr /* 15983666Sdfr // Seconds 16083666Sdfr */ 16183666Sdfr UTime += ETime->Second; 16283666Sdfr 16383666Sdfr return UTime; 16483666Sdfr} 16583666Sdfr 16683666Sdfrtime_t 16783364Sdfrtime(time_t *tloc) 16883364Sdfr{ 16983666Sdfr struct ssc_time time; 17083666Sdfr 17183666Sdfr ssc((u_int64_t) &time, 0, 0, 0, SSC_GET_RTC); 17283666Sdfr 17383666Sdfr return *tloc = EfiTimeToUnixTime(&time); 17483364Sdfr} 175