1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/o_time.c -*- mode:C; c-file-style: "eay" -*- */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * project 2001. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 5480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 6480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * project 2008. 7480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ==================================================================== 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the documentation and/or other materials provided with the 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * distribution. 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * software must display the following acknowledgment: 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * endorse or promote products derived from this software without 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * prior written permission. For written permission, please contact 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * licensing@OpenSSL.org. 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL" 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * nor may "OpenSSL" appear in their names without prior written 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * permission of the OpenSSL Project. 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * acknowledgment: 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE. 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ==================================================================== 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com). This product includes software written by Tim 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com). 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/e_os2.h> 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <string.h> 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "o_time.h" 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_VMS 67480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# if __CRTL_VER >= 70000000 && \ 68480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE) 69480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# define VMS_GMTIME_OK 70480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# endif 71480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# ifndef VMS_GMTIME_OK 72480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# include <libdtdef.h> 73480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# include <lib$routines.h> 74480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# include <lnmdef.h> 75480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# include <starlet.h> 76480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# include <descrip.h> 77480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# include <stdlib.h> 78480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org# endif /* ndef VMS_GMTIME_OK */ 79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstruct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) 82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct tm *ts = NULL; 84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 85480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) 86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* should return &data, but doesn't on some systems, 87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org so we don't even look at the return value */ 88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org gmtime_r(timer,result); 89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ts = result; 90480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK) 91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ts = gmtime(timer); 92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ts == NULL) 93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memcpy(result, ts, sizeof(struct tm)); 96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ts = result; 97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 98480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK) 99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ts == NULL) 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org static $DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL"); 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org static $DESCRIPTOR(lognam,"SYS$TIMEZONE_DIFFERENTIAL"); 103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org char logvalue[256]; 104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int reslen = 0; 105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct { 106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org short buflen; 107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org short code; 108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *bufaddr; 109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int *reslen; 110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } itemlist[] = { 111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 0, LNM$_STRING, 0, 0 }, 112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 0, 0, 0, 0 }, 113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org }; 114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int status; 115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org time_t t; 116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ 118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org itemlist[0].buflen = sizeof(logvalue); 119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org itemlist[0].bufaddr = logvalue; 120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org itemlist[0].reslen = &reslen; 121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); 122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(status & 1)) 123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org logvalue[reslen] = '\0'; 125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org t = *timer; 127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* The following is extracted from the DEC C header time.h */ 129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org** have two implementations. One implementation is provided 132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org** for compatibility and deals with time in terms of local time, 133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org** the other __utc_* deals with time in terms of UTC. 134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org*/ 135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* We use the same conditions as in said time.h to check if we should 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org assume that t contains local time (and should therefore be adjusted) 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org or UTC (and should therefore be left untouched). */ 138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE 139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Get the numerical value of the equivalence string */ 140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = atoi(logvalue); 141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* and use it to move time to GMT */ 143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org t -= status; 144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* then convert the result to the time structure */ 147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Since there was no gmtime_r() to do this stuff for us, 149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org we have to do it the hard way. */ 150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* The VMS epoch is the astronomical Smithsonian date, 152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if I remember correctly, which is November 17, 1858. 153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org Furthermore, time is measure in thenths of microseconds 154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org and stored in quadwords (64 bit integers). unix_epoch 155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org below is January 1st 1970 expressed as a VMS time. The 156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org following code was used to get this number: 157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org #include <stdio.h> 159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org #include <stdlib.h> 160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org #include <lib$routines.h> 161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org #include <starlet.h> 162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org main() 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned long systime[2]; 166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned short epoch_values[7] = 167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1970, 1, 1, 0, 0, 0, 0 }; 168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org lib$cvt_vectim(epoch_values, systime); 170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org printf("%u %u", systime[0], systime[1]); 172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned long unix_epoch[2] = { 1273708544, 8164711 }; 175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned long deltatime[2]; 176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned long systime[2]; 177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct vms_vectime 178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org short year, month, day, hour, minute, second, 180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org centi_second; 181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } time_values; 182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org long operation; 183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Turn the number of seconds since January 1st 1970 to 185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org an internal delta time. 186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org Note that lib$cvt_to_internal_time() will assume 187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org that t is signed, and will therefore break on 32-bit 188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org systems some time in 2038. 189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org operation = LIB$K_DELTA_SECONDS; 191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = lib$cvt_to_internal_time(&operation, 192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &t, deltatime); 193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Add the delta time with the Unix epoch and we have 195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org the current UTC time in internal format */ 196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = lib$add_times(unix_epoch, deltatime, systime); 197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Turn the internal time into a time vector */ 199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = sys$numtim(&time_values, systime); 200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Fill in the struct tm with the result */ 202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_sec = time_values.second; 203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_min = time_values.minute; 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_hour = time_values.hour; 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_mday = time_values.day; 206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_mon = time_values.month - 1; 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_year = time_values.year - 1900; 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org operation = LIB$K_DAY_OF_WEEK; 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = lib$cvt_from_internal_time(&operation, 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &result->tm_wday, systime); 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_wday %= 7; 213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org operation = LIB$K_DAY_OF_YEAR; 215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org status = lib$cvt_from_internal_time(&operation, 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &result->tm_yday, systime); 217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_yday--; 218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org result->tm_isdst = 0; /* There's no way to know... */ 220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ts = result; 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ts; 226480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 227480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 228480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Take a tm structure and add an offset to it. This avoids any OS issues 229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * with restricted date types and overflows which cause the year 2038 230480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * problem. 231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 232480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 233480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define SECS_PER_DAY (24 * 60 * 60) 234480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic long date_to_julian(int y, int m, int d); 236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void julian_to_date(long jd, int *y, int *m, int *d); 237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 238480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) 239480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 240480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int offset_hms, offset_day; 241480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org long time_jd; 242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int time_year, time_month, time_day; 243480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* split offset into days and day seconds */ 244480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_day = offset_sec / SECS_PER_DAY; 245480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Avoid sign issues with % operator */ 246480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_hms = offset_sec - (offset_day * SECS_PER_DAY); 247480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_day += off_day; 248480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Add current time seconds to offset */ 249480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; 250480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Adjust day seconds if overflow */ 251480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (offset_hms >= SECS_PER_DAY) 252480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 253480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_day++; 254480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_hms -= SECS_PER_DAY; 255480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 256480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else if (offset_hms < 0) 257480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 258480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_day--; 259480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org offset_hms += SECS_PER_DAY; 260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Convert date of time structure into a Julian day number. 263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 264480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 265480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time_year = tm->tm_year + 1900; 266480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time_month = tm->tm_mon + 1; 267480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time_day = tm->tm_mday; 268480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 269480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time_jd = date_to_julian(time_year, time_month, time_day); 270480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 271480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Work out Julian day of new date */ 272480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time_jd += offset_day; 273480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 274480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (time_jd < 0) 275480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 276480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 277480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Convert Julian day back to date */ 278480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 279480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org julian_to_date(time_jd, &time_year, &time_month, &time_day); 280480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 281480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (time_year < 1900 || time_year > 9999) 282480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 283480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Update tm structure */ 285480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm->tm_year = time_year - 1900; 287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm->tm_mon = time_month - 1; 288480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm->tm_mday = time_day; 289480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 290480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm->tm_hour = offset_hms / 3600; 291480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm->tm_min = (offset_hms / 60) % 60; 292480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm->tm_sec = offset_hms % 60; 293480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 294480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 295480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 296480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org} 297480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 298480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Convert date to and from julian day 299480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Uses Fliegel & Van Flandern algorithm 300480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 301480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic long date_to_julian(int y, int m, int d) 302480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{ 303480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + 304480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - 305480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + 306480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org d - 32075; 307480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org} 308480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 309480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void julian_to_date(long jd, int *y, int *m, int *d) 310480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 311480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org long L = jd + 68569; 312480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org long n = (4 * L) / 146097; 313480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org long i, j; 314480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 315480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org L = L - (146097 * n + 3) / 4; 316480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org i = (4000 * (L + 1)) / 1461001; 317480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org L = L - (1461 * i) / 4 + 31; 318480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org j = (80 * L) / 2447; 319480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *d = L - (2447 * j) / 80; 320480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org L = j / 11; 321480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *m = j + 2 - (12 * L); 322480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *y = 100 * (n - 49) + i + L; 323480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 324480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 325480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#ifdef OPENSSL_TIME_TEST 326480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 327480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#include <stdio.h> 328480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 329480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Time checking test code. Check times are identical for a wide range of 330480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * offsets. This should be run on a machine with 64 bit time_t or it will 331480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * trigger the very errors the routines fix. 332480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 333480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 334480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint main(int argc, char **argv) 335480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 336480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org long offset; 337480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (offset = 0; offset < 1000000; offset++) 338480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 339480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org check_time(offset); 340480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org check_time(-offset); 341480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org check_time(offset * 1000); 342480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org check_time(-offset * 1000); 343480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 344480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 345480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 346480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint check_time(long offset) 347480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 348480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct tm tm1, tm2; 349480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time_t t1, t2; 350480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org time(&t1); 351480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org t2 = t1 + offset; 352480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_gmtime(&t2, &tm2); 353480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_gmtime(&t1, &tm1); 354480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_gmtime_adj(&tm1, 0, offset); 355480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ((tm1.tm_year == tm2.tm_year) && 356480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (tm1.tm_mon == tm2.tm_mon) && 357480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (tm1.tm_mday == tm2.tm_mday) && 358480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (tm1.tm_hour == tm2.tm_hour) && 359480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (tm1.tm_min == tm2.tm_min) && 360480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (tm1.tm_sec == tm2.tm_sec)) 361480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 362480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org fprintf(stderr, "TIME ERROR!!\n"); 363480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n", 364480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900, 365480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm2.tm_hour, tm2.tm_min, tm2.tm_sec); 366480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n", 367480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900, 368480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tm1.tm_hour, tm1.tm_min, tm1.tm_sec); 369480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 370480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 371480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 372480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 373