1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/o_time.c -*- mode:C; c-file-style: "eay" -*- */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 2001.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * project 2008.
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/e_os2.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "o_time.h"
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef OPENSSL_SYS_VMS
67ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom# if __CRTL_VER >= 70000000 && \
68ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom     (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE)
69ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  define VMS_GMTIME_OK
70ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom# endif
71ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom# ifndef VMS_GMTIME_OK
72ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  include <libdtdef.h>
73ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  include <lib$routines.h>
74ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  include <lnmdef.h>
75ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  include <starlet.h>
76ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  include <descrip.h>
77ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#  include <stdlib.h>
78ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom# endif /* ndef VMS_GMTIME_OK */
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct tm *ts = NULL;
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#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)
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* should return &data, but doesn't on some systems,
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	   so we don't even look at the return value */
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	gmtime_r(timer,result);
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ts = result;
90ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ts = gmtime(timer);
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ts == NULL)
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memcpy(result, ts, sizeof(struct tm));
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ts = result;
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
98ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK)
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ts == NULL)
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		static $DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL");
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		static $DESCRIPTOR(lognam,"SYS$TIMEZONE_DIFFERENTIAL");
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char logvalue[256];
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int reslen = 0;
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		struct {
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			short buflen;
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			short code;
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			void *bufaddr;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned int *reslen;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} itemlist[] = {
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{ 0, LNM$_STRING, 0, 0 },
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{ 0, 0, 0, 0 },
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		};
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		int status;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		time_t t;
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		itemlist[0].buflen = sizeof(logvalue);
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		itemlist[0].bufaddr = logvalue;
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		itemlist[0].reslen = &reslen;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(status & 1))
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return NULL;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		logvalue[reslen] = '\0';
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		t = *timer;
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The following is extracted from the DEC C header time.h */
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project**  Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project**  have two implementations.  One implementation is provided
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project**  for compatibility and deals with time in terms of local time,
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project**  the other __utc_* deals with time in terms of UTC.
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project*/
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* We use the same conditions as in said time.h to check if we should
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   assume that t contains local time (and should therefore be adjusted)
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   or UTC (and should therefore be left untouched). */
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Get the numerical value of the equivalence string */
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = atoi(logvalue);
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* and use it to move time to GMT */
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		t -= status;
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* then convert the result to the time structure */
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Since there was no gmtime_r() to do this stuff for us,
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   we have to do it the hard way. */
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* The VMS epoch is the astronomical Smithsonian date,
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   if I remember correctly, which is November 17, 1858.
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   Furthermore, time is measure in thenths of microseconds
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   and stored in quadwords (64 bit integers).  unix_epoch
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   below is January 1st 1970 expressed as a VMS time.  The
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   following code was used to get this number:
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   #include <stdio.h>
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   #include <stdlib.h>
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   #include <lib$routines.h>
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   #include <starlet.h>
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   main()
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   {
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     unsigned long systime[2];
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     unsigned short epoch_values[7] =
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		       { 1970, 1, 1, 0, 0, 0, 0 };
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     lib$cvt_vectim(epoch_values, systime);
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     printf("%u %u", systime[0], systime[1]);
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   }
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*/
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned long unix_epoch[2] = { 1273708544, 8164711 };
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned long deltatime[2];
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned long systime[2];
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		struct vms_vectime
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			short year, month, day, hour, minute, second,
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				centi_second;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			} time_values;
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		long operation;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Turn the number of seconds since January 1st 1970 to
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   an internal delta time.
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   Note that lib$cvt_to_internal_time() will assume
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   that t is signed, and will therefore break on 32-bit
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   systems some time in 2038.
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*/
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		operation = LIB$K_DELTA_SECONDS;
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = lib$cvt_to_internal_time(&operation,
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&t, deltatime);
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Add the delta time with the Unix epoch and we have
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   the current UTC time in internal format */
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = lib$add_times(unix_epoch, deltatime, systime);
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Turn the internal time into a time vector */
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = sys$numtim(&time_values, systime);
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Fill in the struct tm with the result */
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_sec = time_values.second;
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_min = time_values.minute;
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_hour = time_values.hour;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_mday = time_values.day;
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_mon = time_values.month - 1;
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_year = time_values.year - 1900;
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		operation = LIB$K_DAY_OF_WEEK;
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = lib$cvt_from_internal_time(&operation,
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&result->tm_wday, systime);
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_wday %= 7;
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		operation = LIB$K_DAY_OF_YEAR;
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		status = lib$cvt_from_internal_time(&operation,
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&result->tm_yday, systime);
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_yday--;
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		result->tm_isdst = 0; /* There's no way to know... */
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ts = result;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ts;
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Take a tm structure and add an offset to it. This avoids any OS issues
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * with restricted date types and overflows which cause the year 2038
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * problem.
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define SECS_PER_DAY (24 * 60 * 60)
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic long date_to_julian(int y, int m, int d);
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void julian_to_date(long jd, int *y, int *m, int *d);
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int offset_hms, offset_day;
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long time_jd;
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int time_year, time_month, time_day;
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* split offset into days and day seconds */
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	offset_day = offset_sec / SECS_PER_DAY;
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Avoid sign issues with % operator */
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	offset_hms  = offset_sec - (offset_day * SECS_PER_DAY);
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	offset_day += off_day;
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Add current time seconds to offset */
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Adjust day seconds if overflow */
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (offset_hms >= SECS_PER_DAY)
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		offset_day++;
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		offset_hms -= SECS_PER_DAY;
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else if (offset_hms < 0)
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		offset_day--;
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		offset_hms += SECS_PER_DAY;
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Convert date of time structure into a Julian day number.
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 */
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time_year = tm->tm_year + 1900;
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time_month = tm->tm_mon + 1;
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time_day = tm->tm_mday;
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time_jd = date_to_julian(time_year, time_month, time_day);
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Work out Julian day of new date */
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time_jd += offset_day;
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (time_jd < 0)
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Convert Julian day back to date */
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	julian_to_date(time_jd, &time_year, &time_month, &time_day);
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (time_year < 1900 || time_year > 9999)
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Update tm structure */
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tm->tm_year = time_year - 1900;
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tm->tm_mon = time_month - 1;
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tm->tm_mday = time_day;
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tm->tm_hour = offset_hms / 3600;
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tm->tm_min = (offset_hms / 60) % 60;
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tm->tm_sec = offset_hms % 60;
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Convert date to and from julian day
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Uses Fliegel & Van Flandern algorithm
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic long date_to_julian(int y, int m, int d)
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		(367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		(3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 +
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		d - 32075;
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void julian_to_date(long jd, int *y, int *m, int *d)
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long  L = jd + 68569;
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long  n = (4 * L) / 146097;
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long  i, j;
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	L = L - (146097 * n + 3) / 4;
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	i = (4000 * (L + 1)) / 1461001;
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	L = L - (1461 * i) / 4 + 31;
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	j = (80 * L) / 2447;
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*d = L - (2447 * j) / 80;
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	L = j / 11;
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*m = j + 2 - (12 * L);
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*y = 100 * (n - 49) + i + L;
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef OPENSSL_TIME_TEST
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <stdio.h>
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Time checking test code. Check times are identical for a wide range of
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * offsets. This should be run on a machine with 64 bit time_t or it will
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * trigger the very errors the routines fix.
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint main(int argc, char **argv)
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long offset;
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (offset = 0; offset < 1000000; offset++)
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		check_time(offset);
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		check_time(-offset);
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		check_time(offset * 1000);
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		check_time(-offset * 1000);
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint check_time(long offset)
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct tm tm1, tm2;
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time_t t1, t2;
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	time(&t1);
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	t2 = t1 + offset;
352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_gmtime(&t2, &tm2);
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_gmtime(&t1, &tm1);
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_gmtime_adj(&tm1, 0, offset);
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((tm1.tm_year == tm2.tm_year) &&
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    (tm1.tm_mon == tm2.tm_mon) &&
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    (tm1.tm_mday == tm2.tm_mday) &&
358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    (tm1.tm_hour == tm2.tm_hour) &&
359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    (tm1.tm_min == tm2.tm_min) &&
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    (tm1.tm_sec == tm2.tm_sec))
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	fprintf(stderr, "TIME ERROR!!\n");
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n",
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900,
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			tm2.tm_hour, tm2.tm_min, tm2.tm_sec);
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n",
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900,
368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
373