svn commit: samba r17809 - in branches/SAMBA_3_0/source/lib: .

jra at samba.org jra at samba.org
Thu Aug 24 20:51:58 GMT 2006


Author: jra
Date: 2006-08-24 20:51:57 +0000 (Thu, 24 Aug 2006)
New Revision: 17809

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17809

Log:
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.

Modified:
   branches/SAMBA_3_0/source/lib/time.c


Changeset:
Modified: branches/SAMBA_3_0/source/lib/time.c
===================================================================
--- branches/SAMBA_3_0/source/lib/time.c	2006-08-24 20:49:26 UTC (rev 17808)
+++ branches/SAMBA_3_0/source/lib/time.c	2006-08-24 20:51:57 UTC (rev 17809)
@@ -190,8 +190,14 @@
 	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
  It's originally in "100ns units since jan 1st 1601"
@@ -204,14 +210,130 @@
  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 @@
 	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 @@
 	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 @@
 {
 	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 @@
 	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;
 	}
 
@@ -294,26 +407,6 @@
 }
 
 /****************************************************************************
- 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,15 +431,41 @@
 	}		
 
 	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.
 ****************************************************************************/
 



More information about the samba-cvs mailing list