mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
r17809: Add in 64-bit integer time calculations (taken from
Samba4) for machines that have 64-bit integers. Leave the (double) code for machines that don't. Needs testing.... :-). Jeremy. (This used to be commit 9e65c175b0794bea3082785b5da6f5b281887ce7)
This commit is contained in:
parent
22c7238825
commit
01bb24624d
@ -190,7 +190,13 @@ struct timespec convert_time_t_to_timespec(time_t t)
|
||||
return ts;
|
||||
}
|
||||
|
||||
#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
|
||||
#ifdef uint64
|
||||
|
||||
#if (SIZEOF_LONG == 8)
|
||||
#define TIME_FIXUP_CONSTANT_INT 11644473600L
|
||||
#elif (SIZEOF_LONG_LONG == 8)
|
||||
#define TIME_FIXUP_CONSTANT_INT 11644473600LL
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Interpret an 8 byte "filetime" structure to a time_t
|
||||
@ -204,14 +210,130 @@ struct timespec convert_time_t_to_timespec(time_t t)
|
||||
Returns GMT.
|
||||
****************************************************************************/
|
||||
|
||||
/* Large integer version. */
|
||||
static struct timespec nt_time_to_unix_timespec(NTTIME *nt)
|
||||
{
|
||||
uint64 d;
|
||||
struct timespec ret;
|
||||
|
||||
if ((nt->high == 0 && nt->low == 0 )||
|
||||
(nt->high == 0xffffffff && nt->low == 0xffffffff)) {
|
||||
ret.tv_sec = 0;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
d = (((uint64)nt->high) << 32 ) + ((uint64)nt->low);
|
||||
/* d is now in 100ns units, since jan 1st 1601".
|
||||
Save off the ns fraction. */
|
||||
|
||||
ret.tv_nsec = (long) ((d % 100) * 100);
|
||||
|
||||
/* Convert to seconds */
|
||||
d /= 1000*1000*10;
|
||||
|
||||
/* Now adjust by 369 years to make the secs since 1970 */
|
||||
d -= TIME_FIXUP_CONSTANT_INT;
|
||||
|
||||
if (d <= TIME_T_MIN) {
|
||||
ret.tv_sec = TIME_T_MIN;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (d >= TIME_T_MAX) {
|
||||
ret.tv_sec = TIME_T_MAX;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.tv_sec = (time_t)d;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Convert a NTTIME structure to a time_t.
|
||||
It's originally in "100ns units".
|
||||
|
||||
This is an absolute version of the one above.
|
||||
By absolute I mean, it doesn't adjust from 1/1/1601 to 1/1/1970
|
||||
if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM
|
||||
****************************************************************************/
|
||||
|
||||
time_t nt_time_to_unix_abs(const NTTIME *nt)
|
||||
{
|
||||
uint64 d;
|
||||
NTTIME neg_nt;
|
||||
|
||||
if (nt->high == 0) {
|
||||
return (time_t)0;
|
||||
}
|
||||
|
||||
if (nt->high==0x80000000 && nt->low==0) {
|
||||
return (time_t)-1;
|
||||
}
|
||||
|
||||
/* reverse the time */
|
||||
/* it's a negative value, turn it to positive */
|
||||
neg_nt.high=~nt->high;
|
||||
neg_nt.low=~nt->low;
|
||||
|
||||
d = (((uint64)neg_nt.high) << 32 ) + ((uint64)neg_nt.low);
|
||||
|
||||
d += 1000*1000*10/2;
|
||||
d /= 1000*1000*10;
|
||||
|
||||
if (!(TIME_T_MIN <= d && d <= TIME_T_MAX)) {
|
||||
return (time_t)0;
|
||||
}
|
||||
|
||||
return (time_t)d;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Put a 8 byte filetime from a struct timespec. Uses GMT.
|
||||
****************************************************************************/
|
||||
|
||||
void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts)
|
||||
{
|
||||
uint64 d;
|
||||
|
||||
if (ts.tv_sec ==0 && ts.tv_nsec == 0) {
|
||||
nt->low = 0;
|
||||
nt->high = 0;
|
||||
return;
|
||||
}
|
||||
if (ts.tv_sec == TIME_T_MAX) {
|
||||
nt->low = 0xffffffff;
|
||||
nt->high = 0x7fffffff;
|
||||
return;
|
||||
}
|
||||
if (ts.tv_sec == (time_t)-1) {
|
||||
nt->low = 0xffffffff;
|
||||
nt->high = 0xffffffff;
|
||||
return;
|
||||
}
|
||||
|
||||
d = ts.tv_sec;
|
||||
d += TIME_FIXUP_CONSTANT_INT;
|
||||
d = ts.tv_sec * 1000*1000*10;
|
||||
/* d is now in 100ns units. */
|
||||
d += (ts.tv_nsec / 100);
|
||||
|
||||
nt->high = (uint32)(d / 1000*1000*10);
|
||||
nt->low = (uint32)(d % 1000*1000*10);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* No 64-bit datatype. Use double float. */
|
||||
#define TIME_FIXUP_CONSTANT_DOUBLE (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
|
||||
|
||||
/* Floating point double versions. */
|
||||
static struct timespec nt_time_to_unix_timespec(NTTIME *nt)
|
||||
{
|
||||
double d;
|
||||
struct timespec ret;
|
||||
/* The next two lines are a fix needed for the
|
||||
broken SCO compiler. JRA. */
|
||||
time_t l_time_min = TIME_T_MIN;
|
||||
time_t l_time_max = TIME_T_MAX;
|
||||
|
||||
if ((nt->high == 0 && nt->low == 0 )||
|
||||
(nt->high == 0xffffffff && nt->low == 0xffffffff)) {
|
||||
@ -225,16 +347,16 @@ static struct timespec nt_time_to_unix_timespec(NTTIME *nt)
|
||||
d *= 1.0e-7;
|
||||
|
||||
/* now adjust by 369 years to make the secs since 1970 */
|
||||
d -= TIME_FIXUP_CONSTANT;
|
||||
d -= TIME_FIXUP_CONSTANT_DOUBLE;
|
||||
|
||||
if (d <= l_time_min) {
|
||||
ret.tv_sec = l_time_min;
|
||||
if (d <= TIME_T_MIN) {
|
||||
ret.tv_sec = TIME_T_MIN;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (d >= l_time_max) {
|
||||
ret.tv_sec = l_time_max;
|
||||
if (d >= TIME_T_MAX) {
|
||||
ret.tv_sec = TIME_T_MAX;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
@ -244,11 +366,6 @@ static struct timespec nt_time_to_unix_timespec(NTTIME *nt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t nt_time_to_unix(NTTIME *nt)
|
||||
{
|
||||
return convert_timespec_to_time_t(nt_time_to_unix_timespec(nt));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Convert a NTTIME structure to a time_t.
|
||||
It's originally in "100ns units".
|
||||
@ -262,10 +379,6 @@ time_t nt_time_to_unix_abs(const NTTIME *nt)
|
||||
{
|
||||
double d;
|
||||
time_t ret;
|
||||
/* The next two lines are a fix needed for the
|
||||
broken SCO compiler. JRA. */
|
||||
time_t l_time_min = TIME_T_MIN;
|
||||
time_t l_time_max = TIME_T_MAX;
|
||||
NTTIME neg_nt;
|
||||
|
||||
if (nt->high == 0) {
|
||||
@ -285,7 +398,7 @@ time_t nt_time_to_unix_abs(const NTTIME *nt)
|
||||
d += (neg_nt.low&0xFFF00000);
|
||||
d *= 1.0e-7;
|
||||
|
||||
if (!(l_time_min <= d && d <= l_time_max)) {
|
||||
if (!(TIME_T_MIN <= d && d <= TIME_T_MAX)) {
|
||||
return (time_t)0;
|
||||
}
|
||||
|
||||
@ -293,26 +406,6 @@ time_t nt_time_to_unix_abs(const NTTIME *nt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Interprets an nt time into a unix struct timespec.
|
||||
Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
|
||||
will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this case.
|
||||
****************************************************************************/
|
||||
|
||||
struct timespec interpret_long_date(char *p)
|
||||
{
|
||||
NTTIME nt;
|
||||
nt.low = IVAL(p,0);
|
||||
nt.high = IVAL(p,4);
|
||||
if (nt.low == 0xFFFFFFFF && nt.high == 0xFFFFFFFF) {
|
||||
struct timespec ret;
|
||||
ret.tv_sec = (time_t)-1;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
return nt_time_to_unix_timespec(&nt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Put a 8 byte filetime from a struct timespec. Uses GMT.
|
||||
****************************************************************************/
|
||||
@ -338,13 +431,39 @@ void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts)
|
||||
}
|
||||
|
||||
d = (double)(ts.tv_sec);
|
||||
d += TIME_FIXUP_CONSTANT;
|
||||
d += TIME_FIXUP_CONSTANT_DOUBLE;
|
||||
d *= 1.0e7;
|
||||
d += ((double)ts.tv_nsec / 100.0);
|
||||
|
||||
nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
|
||||
nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
|
||||
}
|
||||
#endif
|
||||
|
||||
time_t nt_time_to_unix(NTTIME *nt)
|
||||
{
|
||||
return convert_timespec_to_time_t(nt_time_to_unix_timespec(nt));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Interprets an nt time into a unix struct timespec.
|
||||
Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
|
||||
will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this case.
|
||||
****************************************************************************/
|
||||
|
||||
struct timespec interpret_long_date(char *p)
|
||||
{
|
||||
NTTIME nt;
|
||||
nt.low = IVAL(p,0);
|
||||
nt.high = IVAL(p,4);
|
||||
if (nt.low == 0xFFFFFFFF && nt.high == 0xFFFFFFFF) {
|
||||
struct timespec ret;
|
||||
ret.tv_sec = (time_t)-1;
|
||||
ret.tv_nsec = 0;
|
||||
return ret;
|
||||
}
|
||||
return nt_time_to_unix_timespec(&nt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Put a 8 byte filetime from a time_t. Uses GMT.
|
||||
|
Loading…
x
Reference in New Issue
Block a user