1/*
2 ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
3 ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
4 ** Digital Equipment Corporation, Maynard, Mass.
5 ** Copyright (c) 1998 Microsoft.
6 ** To anyone who acknowledges that this file is provided "AS IS"
7 ** without any express or implied warranty: permission to use, copy,
8 ** modify, and distribute this file for any purpose is hereby
9 ** granted without fee, provided that the above copyright notices and
10 ** this notice appears in all source code copies, and that none of
11 ** the names of Open Software Foundation, Inc., Hewlett-Packard
12 ** Company, or Digital Equipment Corporation be used in advertising
13 ** or publicity pertaining to distribution of the software without
14 ** specific, written prior permission.  Neither Open Software
15 ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
16 ** Corporation makes any representations about the suitability of
17 ** this software for any purpose.
18 */
19
20#include <unistd.h>
21#include <string.h>
22#include <stdio.h>
23#include "sysdep.h"
24
25/*-----------------------------------------------------------------------------*/
26/*
27   system dependent call to get IEEE node ID.
28   This sample implementation generates a random node ID
29 */
30void
31get_ieee_node_identifier( uuid_node_t * node )
32{
33    char seed[16];
34    static int inited = 0;
35    static uuid_node_t saved_node;
36
37    if( !inited ) {
38        get_random_info( seed );
39        seed[0] |= 0x80;
40        memcpy( &saved_node, seed, sizeof( uuid_node_t ) );
41
42        inited = 1;
43    };
44
45    *node = saved_node;
46};
47
48/*-----------------------------------------------------------------------------*/
49/*
50   system dependent call to get the current system time.
51   Returned as 100ns ticks since Oct 15, 1582, but resolution may be
52   less than 100ns.
53 */
54
55#ifdef _WINDOWS_
56
57void
58get_system_time( uuid_time_t * uuid_time )
59{
60    ULARGE_INTEGER time;
61
62    GetSystemTimeAsFileTime( ( FILETIME * ) & time );
63
64    /*
65       NT keeps time in FILETIME format which is 100ns ticks since
66       Jan 1, 1601.  UUIDs use time in 100ns ticks since Oct 15, 1582.
67       The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
68       + 18 years and 5 leap days.
69     */
70
71    time.QuadPart += ( unsigned __int64 )( 1000 * 1000 * 10 )   // seconds
72        * ( unsigned __int64 )( 60 * 60 * 24 )  // days
73        * ( unsigned __int64 )( 17 + 30 + 31 + 365 * 18 + 5 );  // # of days
74
75    *uuid_time = time.QuadPart;
76
77};
78
79/*-----------------------------------------------------------------------------*/
80void
81get_random_info( char seed[16] )
82{
83    MD5_CTX c;
84    typedef struct {
85        MEMORYSTATUS m;
86        SYSTEM_INFO s;
87        FILETIME t;
88        LARGE_INTEGER pc;
89        DWORD tc;
90        DWORD l;
91        char hostname[MAX_COMPUTERNAME_LENGTH + 1];
92    } randomness;
93    randomness r;
94
95    MD5Init( &c );
96    /*
97       memory usage stats
98     */
99    GlobalMemoryStatus( &r.m );
100    /*
101       random system stats
102     */
103    GetSystemInfo( &r.s );
104    /*
105       100ns resolution (nominally) time of day
106     */
107    GetSystemTimeAsFileTime( &r.t );
108    /*
109       high resolution performance counter
110     */
111    QueryPerformanceCounter( &r.pc );
112    /*
113       milliseconds since last boot
114     */
115    r.tc = GetTickCount(  );
116    r.l = MAX_COMPUTERNAME_LENGTH + 1;
117
118    GetComputerName( r.hostname, &r.l );
119    MD5Update( &c, &r, sizeof( randomness ) );
120    MD5Final( seed, &c );
121};
122#else
123
124/*-----------------------------------------------------------------------------*/
125void
126get_system_time( uuid_time_t * uuid_time )
127{
128    struct timeval tp;
129
130    gettimeofday( &tp, ( struct timezone * )0 );
131
132    /*
133       Offset between UUID formatted times and Unix formatted times.
134       UUID UTC base time is October 15, 1582.
135       Unix base time is January 1, 1970.
136     */
137    *uuid_time = ( tp.tv_sec * 10000000 ) + ( tp.tv_usec * 10 ) +
138        I64( 0x01B21DD213814000 );
139};
140
141/*-----------------------------------------------------------------------------*/
142void
143get_random_info( char seed[16] )
144{
145    MD5_CTX c;
146    typedef struct {
147        struct sysinfo s;
148        struct timeval t;
149        char hostname[257];
150    } randomness;
151    randomness r;
152
153    MD5Init( &c );
154
155    gettimeofday( &r.t, ( struct timezone * )0 );
156    gethostname( r.hostname, 256 );
157    MD5Update( &c, &r, sizeof( randomness ) );
158    MD5Final( seed, &c );
159};
160
161#endif
162