
1: /* crypto/o_time.c -*- mode:C; c-file-style: "eay" -*- */ 2: /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL 3: * project 2001. 4: */ 5: /* ==================================================================== 6: * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 7: * 8: * Redistribution and use in source and binary forms, with or without 9: * modification, are permitted provided that the following conditions 10: * are met: 11: * 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 15: * 2. Redistributions in binary form must reproduce the above copyright 16: * notice, this list of conditions and the following disclaimer in 17: * the documentation and/or other materials provided with the 18: * distribution. 19: * 20: * 3. All advertising materials mentioning features or use of this 21: * software must display the following acknowledgment: 22: * "This product includes software developed by the OpenSSL Project 23: * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24: * 25: * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26: * endorse or promote products derived from this software without 27: * prior written permission. For written permission, please contact 28: * licensing@OpenSSL.org. 29: * 30: * 5. Products derived from this software may not be called "OpenSSL" 31: * nor may "OpenSSL" appear in their names without prior written 32: * permission of the OpenSSL Project. 33: * 34: * 6. Redistributions of any form whatsoever must retain the following 35: * acknowledgment: 36: * "This product includes software developed by the OpenSSL Project 37: * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38: * 39: * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50: * OF THE POSSIBILITY OF SUCH DAMAGE. 51: * ==================================================================== 52: * 53: * This product includes cryptographic software written by Eric Young 54: * (eay@cryptsoft.com). This product includes software written by Tim 55: * Hudson (tjh@cryptsoft.com). 56: * 57: */ 58: 59: #include <openssl/e_os2.h> 60: #include <string.h> 61: #include "o_time.h" 62: 63: #ifdef OPENSSL_SYS_VMS 64: # include <libdtdef.h> 65: # include <lib$routines.h> 66: # include <lnmdef.h> 67: # include <starlet.h> 68: # include <descrip.h> 69: # include <stdlib.h> 70: #endif 71: 72: struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) 73: { 74: struct tm *ts = NULL; 75: 76: #if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && !defined(__CYGWIN32__) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) 77: /* should return &data, but doesn't on some systems, 78: so we don't even look at the return value */ 79: gmtime_r(timer,result); 80: ts = result; 81: #elif !defined(OPENSSL_SYS_VMS) 82: ts = gmtime(timer); 83: if (ts == NULL) 84: return NULL; 85: 86: memcpy(result, ts, sizeof(struct tm)); 87: ts = result; 88: #endif 89: #ifdef OPENSSL_SYS_VMS 90: if (ts == NULL) 91: { 92: static $DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL"); 93: static $DESCRIPTOR(lognam,"SYS$TIMEZONE_DIFFERENTIAL"); 94: char logvalue[256]; 95: unsigned int reslen = 0; 96: struct { 97: short buflen; 98: short code; 99: void *bufaddr; 100: unsigned int *reslen; 101: } itemlist[] = { 102: { 0, LNM$_STRING, 0, 0 }, 103: { 0, 0, 0, 0 }, 104: }; 105: int status; 106: time_t t; 107: 108: /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ 109: itemlist[0].buflen = sizeof(logvalue); 110: itemlist[0].bufaddr = logvalue; 111: itemlist[0].reslen = &reslen; 112: status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); 113: if (!(status & 1)) 114: return NULL; 115: logvalue[reslen] = '\0'; 116: 117: t = *timer; 118: 119: /* The following is extracted from the DEC C header time.h */ 120: /* 121: ** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime 122: ** have two implementations. One implementation is provided 123: ** for compatibility and deals with time in terms of local time, 124: ** the other __utc_* deals with time in terms of UTC. 125: */ 126: /* We use the same conditions as in said time.h to check if we should 127: assume that t contains local time (and should therefore be adjusted) 128: or UTC (and should therefore be left untouched). */ 129: #if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE 130: /* Get the numerical value of the equivalence string */ 131: status = atoi(logvalue); 132: 133: /* and use it to move time to GMT */ 134: t -= status; 135: #endif 136: 137: /* then convert the result to the time structure */ 138: 139: /* Since there was no gmtime_r() to do this stuff for us, 140: we have to do it the hard way. */ 141: { 142: /* The VMS epoch is the astronomical Smithsonian date, 143: if I remember correctly, which is November 17, 1858. 144: Furthermore, time is measure in thenths of microseconds 145: and stored in quadwords (64 bit integers). unix_epoch 146: below is January 1st 1970 expressed as a VMS time. The 147: following code was used to get this number: 148: 149: #include <stdio.h> 150: #include <stdlib.h> 151: #include <lib$routines.h> 152: #include <starlet.h> 153: 154: main() 155: { 156: unsigned long systime[2]; 157: unsigned short epoch_values[7] = 158: { 1970, 1, 1, 0, 0, 0, 0 }; 159: 160: lib$cvt_vectim(epoch_values, systime); 161: 162: printf("%u %u", systime[0], systime[1]); 163: } 164: */ 165: unsigned long unix_epoch[2] = { 1273708544, 8164711 }; 166: unsigned long deltatime[2]; 167: unsigned long systime[2]; 168: struct vms_vectime 169: { 170: short year, month, day, hour, minute, second, 171: centi_second; 172: } time_values; 173: long operation; 174: 175: /* Turn the number of seconds since January 1st 1970 to 176: an internal delta time. 177: Note that lib$cvt_to_internal_time() will assume 178: that t is signed, and will therefore break on 32-bit 179: systems some time in 2038. 180: */ 181: operation = LIB$K_DELTA_SECONDS; 182: status = lib$cvt_to_internal_time(&operation, 183: &t, deltatime); 184: 185: /* Add the delta time with the Unix epoch and we have 186: the current UTC time in internal format */ 187: status = lib$add_times(unix_epoch, deltatime, systime); 188: 189: /* Turn the internal time into a time vector */ 190: status = sys$numtim(&time_values, systime); 191: 192: /* Fill in the struct tm with the result */ 193: result->tm_sec = time_values.second; 194: result->tm_min = time_values.minute; 195: result->tm_hour = time_values.hour; 196: result->tm_mday = time_values.day; 197: result->tm_mon = time_values.month - 1; 198: result->tm_year = time_values.year - 1900; 199: 200: operation = LIB$K_DAY_OF_WEEK; 201: status = lib$cvt_from_internal_time(&operation, 202: &result->tm_wday, systime); 203: result->tm_wday %= 7; 204: 205: operation = LIB$K_DAY_OF_YEAR; 206: status = lib$cvt_from_internal_time(&operation, 207: &result->tm_yday, systime); 208: result->tm_yday--; 209: 210: result->tm_isdst = 0; /* There's no way to know... */ 211: 212: ts = result; 213: } 214: } 215: #endif 216: return ts; 217: }