155714Skris/* crypto/tmdiff.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris#include <stdio.h>
5955714Skris#include <stdlib.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/tmdiff.h>
62109998Smarkm#if !defined(OPENSSL_SYS_MSDOS)
63296465Sdelphij# include OPENSSL_UNISTD
64109998Smarkm#endif
6555714Skris
6655714Skris#ifdef TIMEB
67296465Sdelphij# undef OPENSSL_SYS_WIN32
68296465Sdelphij# undef TIMES
6955714Skris#endif
7055714Skris
71109998Smarkm#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) && !(defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX_RHAPSODY) && !defined(OPENSSL_SYS_VXWORKS)
72109998Smarkm# define TIMES
7355714Skris#endif
7455714Skris
75160814Ssimon#ifdef OPENSSL_SYS_NETWARE
76296465Sdelphij# undef TIMES
77160814Ssimon#endif
78160814Ssimon
79160814Ssimon#if !defined(_IRIX) || defined (OPENSSL_SYS_NETWARE)
80296465Sdelphij# include <time.h>
8155714Skris#endif
8255714Skris#ifdef TIMES
83296465Sdelphij# include <sys/types.h>
84296465Sdelphij# include <sys/times.h>
8555714Skris#endif
8655714Skris
87296465Sdelphij/*
88296465Sdelphij * Depending on the VMS version, the tms structure is perhaps defined. The
89296465Sdelphij * __TMS macro will show if it was.  If it wasn't defined, we should undefine
90296465Sdelphij * TIMES, since that tells the rest of the program how things should be
91296465Sdelphij * handled.  -- Richard Levitte
92296465Sdelphij */
93109998Smarkm#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
94296465Sdelphij# undef TIMES
9555714Skris#endif
9655714Skris
9755714Skris#if defined(sun) || defined(__ultrix)
98296465Sdelphij# define _POSIX_SOURCE
99296465Sdelphij# include <limits.h>
100296465Sdelphij# include <sys/param.h>
10155714Skris#endif
10255714Skris
103160814Ssimon#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE)
104296465Sdelphij# include <sys/timeb.h>
10555714Skris#endif
10655714Skris
107109998Smarkm#ifdef OPENSSL_SYS_WIN32
108296465Sdelphij# include <windows.h>
10955714Skris#endif
11055714Skris
11155714Skris/* The following if from times(3) man page.  It may need to be changed */
11255714Skris#ifndef HZ
113109998Smarkm# if defined(_SC_CLK_TCK) \
114109998Smarkm     && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000)
115160814Ssimon/* #  define HZ ((double)sysconf(_SC_CLK_TCK)) */
116160814Ssimon#  define HZ sysconf(_SC_CLK_TCK)
117109998Smarkm# else
118109998Smarkm#  ifndef CLK_TCK
119296465Sdelphij#   ifndef _BSD_CLK_TCK_        /* FreeBSD hack */
120109998Smarkm#    define HZ  100.0
121296465Sdelphij#   else                        /* _BSD_CLK_TCK_ */
122109998Smarkm#    define HZ ((double)_BSD_CLK_TCK_)
123109998Smarkm#   endif
124296465Sdelphij#  else                         /* CLK_TCK */
125109998Smarkm#   define HZ ((double)CLK_TCK)
12655714Skris#  endif
12755714Skris# endif
12855714Skris#endif
12955714Skris
130296465Sdelphijstruct ms_tm {
13155714Skris#ifdef TIMES
132296465Sdelphij    struct tms ms_tms;
13355714Skris#else
134296465Sdelphij# ifdef OPENSSL_SYS_WIN32
135296465Sdelphij    HANDLE thread_id;
136296465Sdelphij    FILETIME ms_win32;
137296465Sdelphij# elif defined (OPENSSL_SYS_NETWARE)
138296465Sdelphij    clock_t ms_clock;
139296465Sdelphij# else
140296465Sdelphij#  ifdef OPENSSL_SYS_VXWORKS
141296465Sdelphij    unsigned long ticks;
14255714Skris#  else
143296465Sdelphij    struct timeb ms_timeb;
14455714Skris#  endif
145296465Sdelphij# endif
14655714Skris#endif
147296465Sdelphij};
14855714Skris
149160814SsimonMS_TM *ms_time_new(void)
150296465Sdelphij{
151296465Sdelphij    MS_TM *ret;
15255714Skris
153296465Sdelphij    ret = (MS_TM *) OPENSSL_malloc(sizeof(MS_TM));
154296465Sdelphij    if (ret == NULL)
155296465Sdelphij        return (NULL);
156296465Sdelphij    memset(ret, 0, sizeof(MS_TM));
157109998Smarkm#ifdef OPENSSL_SYS_WIN32
158296465Sdelphij    ret->thread_id = GetCurrentThread();
15955714Skris#endif
160296465Sdelphij    return ret;
161296465Sdelphij}
16255714Skris
163296465Sdelphijvoid ms_time_free(MS_TM * a)
164296465Sdelphij{
165296465Sdelphij    if (a != NULL)
166296465Sdelphij        OPENSSL_free(a);
167296465Sdelphij}
16855714Skris
169296465Sdelphijvoid ms_time_get(MS_TM * tm)
170296465Sdelphij{
171109998Smarkm#ifdef OPENSSL_SYS_WIN32
172296465Sdelphij    FILETIME tmpa, tmpb, tmpc;
17355714Skris#endif
17455714Skris
17555714Skris#ifdef TIMES
176296465Sdelphij    times(&tm->ms_tms);
17755714Skris#else
178296465Sdelphij# ifdef OPENSSL_SYS_WIN32
179296465Sdelphij    GetThreadTimes(tm->thread_id, &tmpa, &tmpb, &tmpc, &(tm->ms_win32));
180296465Sdelphij# elif defined (OPENSSL_SYS_NETWARE)
181296465Sdelphij    tm->ms_clock = clock();
182296465Sdelphij# else
183296465Sdelphij#  ifdef OPENSSL_SYS_VXWORKS
184296465Sdelphij    tm->ticks = tickGet();
18555714Skris#  else
186296465Sdelphij    ftime(&tm->ms_timeb);
18755714Skris#  endif
188296465Sdelphij# endif
18955714Skris#endif
190296465Sdelphij}
19155714Skris
192296465Sdelphijdouble ms_time_diff(MS_TM * a, MS_TM * b)
193296465Sdelphij{
194296465Sdelphij    double ret;
19555714Skris
19655714Skris#ifdef TIMES
197296465Sdelphij    ret = HZ;
198296465Sdelphij    ret = (b->ms_tms.tms_utime - a->ms_tms.tms_utime) / ret;
19955714Skris#else
200109998Smarkm# ifdef OPENSSL_SYS_WIN32
201296465Sdelphij    {
202296465Sdelphij#  ifdef __GNUC__
203296465Sdelphij        signed long long la, lb;
204296465Sdelphij#  else
205296465Sdelphij        signed _int64 la, lb;
206296465Sdelphij#  endif
207296465Sdelphij        la = a->ms_win32.dwHighDateTime;
208296465Sdelphij        lb = b->ms_win32.dwHighDateTime;
209296465Sdelphij        la <<= 32;
210296465Sdelphij        lb <<= 32;
211296465Sdelphij        la += a->ms_win32.dwLowDateTime;
212296465Sdelphij        lb += b->ms_win32.dwLowDateTime;
213296465Sdelphij        ret = ((double)(lb - la)) / 1e7;
214296465Sdelphij    }
215160814Ssimon# elif defined (OPENSSL_SYS_NETWARE)
216296465Sdelphij    ret = (double)(b->ms_clock - a->ms_clock);
21755714Skris# else
218109998Smarkm#  ifdef OPENSSL_SYS_VXWORKS
219296465Sdelphij    ret = (double)(b->ticks - a->ticks) / (double)sysClkRateGet();
220100928Snectar#  else
221296465Sdelphij    ret = (double)(b->ms_timeb.time - a->ms_timeb.time) +
222296465Sdelphij        (((double)b->ms_timeb.millitm) -
223296465Sdelphij         ((double)a->ms_timeb.millitm)) / 1000.0;
22455714Skris#  endif
225100928Snectar# endif
22655714Skris#endif
227296465Sdelphij    return ((ret < 0.0000001) ? 0.0000001 : ret);
228296465Sdelphij}
22955714Skris
230296465Sdelphijint ms_time_cmp(const MS_TM * a, const MS_TM * b)
231296465Sdelphij{
232296465Sdelphij    double d;
233296465Sdelphij    int ret;
23455714Skris
23555714Skris#ifdef TIMES
236296465Sdelphij    d = HZ;
237296465Sdelphij    d = (b->ms_tms.tms_utime - a->ms_tms.tms_utime) / d;
23855714Skris#else
239109998Smarkm# ifdef OPENSSL_SYS_WIN32
240296465Sdelphij    d = (b->ms_win32.dwHighDateTime & 0x000fffff) * 10 +
241296465Sdelphij        b->ms_win32.dwLowDateTime / 1e7;
242296465Sdelphij    d -= (a->ms_win32.dwHighDateTime & 0x000fffff) * 10 +
243296465Sdelphij        a->ms_win32.dwLowDateTime / 1e7;
244160814Ssimon# elif defined (OPENSSL_SYS_NETWARE)
245296465Sdelphij    d = (double)(b->ms_clock - a->ms_clock);
24655714Skris# else
247109998Smarkm#  ifdef OPENSSL_SYS_VXWORKS
248296465Sdelphij    d = (b->ticks - a->ticks);
249100928Snectar#  else
250296465Sdelphij    d = (double)(b->ms_timeb.time - a->ms_timeb.time) +
251296465Sdelphij        (((double)b->ms_timeb.millitm) -
252296465Sdelphij         (double)a->ms_timeb.millitm) / 1000.0;
25355714Skris#  endif
254100928Snectar# endif
25555714Skris#endif
256296465Sdelphij    if (d == 0.0)
257296465Sdelphij        ret = 0;
258296465Sdelphij    else if (d < 0)
259296465Sdelphij        ret = -1;
260296465Sdelphij    else
261296465Sdelphij        ret = 1;
262296465Sdelphij    return (ret);
263296465Sdelphij}
264