Added init_nt_time function which initialises an NTTIME to -1.
[samba.git] / source / lib / time.c
index 62a7016994d717ee0d515497fcaa6efaacb9e987..85f6006389950f61c1112005290f7ccad510c50b 100644 (file)
@@ -51,10 +51,10 @@ a gettimeofday wrapper
 ********************************************************************/
 void GetTimeOfDay(struct timeval *tval)
 {
-#ifdef GETTIMEOFDAY1
-  gettimeofday(tval);
+#ifdef HAVE_GETTIMEOFDAY_TZ
+       gettimeofday(tval,NULL);
 #else
-  gettimeofday(tval,NULL);
+       gettimeofday(tval);
 #endif
 }
 
@@ -79,12 +79,20 @@ static int tm_diff(struct tm *a, struct tm *b)
 }
 
 /*******************************************************************
-  return the UTC offset in seconds west of UTC
+  return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
   ******************************************************************/
 static int TimeZone(time_t t)
 {
-  struct tm tm_utc = *(gmtime(&t));
-  return tm_diff(&tm_utc,localtime(&t));
+  struct tm *tm = gmtime(&t);
+  struct tm tm_utc;
+  if (!tm)
+    return 0;
+  tm_utc = *tm;
+  tm = localtime(&t);
+  if (!tm)
+    return 0;
+  return tm_diff(&tm_utc,tm);
+
 }
 
 
@@ -217,7 +225,7 @@ static int LocTimeDiff(time_t lte)
 
 
 /****************************************************************************
-try to optimise the localtime call, it can be quite expenive on some machines
+try to optimise the localtime call, it can be quite expensive on some machines
 ****************************************************************************/
 struct tm *LocalTime(time_t *t)
 {
@@ -228,7 +236,6 @@ struct tm *LocalTime(time_t *t)
   return(gmtime(&t2));
 }
 
-
 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
 
 /****************************************************************************
@@ -240,24 +247,25 @@ its the GMT you get by taking a localtime and adding the
 serverzone. This is NOT the same as GMT in some cases. This routine
 converts this to real GMT.
 ****************************************************************************/
-time_t interpret_long_date(char *p)
+time_t nt_time_to_unix(NTTIME *nt)
 {
   double d;
   time_t ret;
-  uint32 tlow,thigh;
-  tlow = IVAL(p,0);
-  thigh = IVAL(p,4);
+  /* 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 (thigh == 0) return(0);
+  if (nt->high == 0) return(0);
 
-  d = ((double)thigh)*4.0*(double)(1<<30);
-  d += (tlow&0xFFF00000);
+  d = ((double)nt->high)*4.0*(double)(1<<30);
+  d += (nt->low&0xFFF00000);
   d *= 1.0e-7;
  
   /* now adjust by 369 years to make the secs since 1970 */
   d -= TIME_FIXUP_CONSTANT;
 
-  if (!(TIME_T_MIN <= d && d <= TIME_T_MAX))
+  if (!(l_time_min <= d && d <= l_time_max))
     return(0);
 
   ret = (time_t)(d+0.5);
@@ -270,36 +278,58 @@ time_t interpret_long_date(char *p)
 }
 
 
+
+/****************************************************************************
+interprets an nt time into a unix time_t
+****************************************************************************/
+time_t interpret_long_date(char *p)
+{
+       NTTIME nt;
+       nt.low = IVAL(p,0);
+       nt.high = IVAL(p,4);
+       return nt_time_to_unix(&nt);
+}
+
 /****************************************************************************
 put a 8 byte filetime from a time_t
 This takes real GMT as input and converts to kludge-GMT
 ****************************************************************************/
-void put_long_date(char *p,time_t t)
+void unix_to_nt_time(NTTIME *nt, time_t t)
 {
-  uint32 tlow,thigh;
-  double d;
-
-  if (t==0) {
-    SIVAL(p,0,0); SIVAL(p,4,0);
-    return;
-  }
+       double d;
 
-  /* this converts GMT to kludge-GMT */
-  t -= LocTimeDiff(t) - serverzone; 
+       /* this converts GMT to kludge-GMT */
+       t -= LocTimeDiff(t) - serverzone; 
 
-  d = (double) (t);
+       d = (double)(t);
+       d += TIME_FIXUP_CONSTANT;
+       d *= 1.0e7;
 
-  d += TIME_FIXUP_CONSTANT;
-
-  d *= 1.0e7;
+       nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
+       nt->low  = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
+}
 
-  thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
-  tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
+/****************************************************************************
+initialise an NTTIME to -1, which means "unknown" or "don't expire"
+****************************************************************************/
 
-  SIVAL(p,0,tlow);
-  SIVAL(p,4,thigh);
+void init_nt_time(NTTIME *nt)
+{
+       nt->high = 0x7FFFFFFF;
+       nt->low = 0xFFFFFFFF;
 }
 
+/****************************************************************************
+take an NTTIME structure, containing high / low time.  convert to unix time.
+lkclXXXX this may need 2 SIVALs not a memcpy.  we'll see...
+****************************************************************************/
+void put_long_date(char *p,time_t t)
+{
+       NTTIME nt;
+       unix_to_nt_time(&nt, t);
+       SIVAL(p, 0, nt.low);
+       SIVAL(p, 4, nt.high);
+}
 
 /****************************************************************************
 check if it's a null mtime
@@ -314,7 +344,7 @@ BOOL null_mtime(time_t mtime)
 /*******************************************************************
   create a 16 bit dos packed date
 ********************************************************************/
-static uint16 make_dos_date1(time_t unixdate,struct tm *t)
+static uint16 make_dos_date1(struct tm *t)
 {
   uint16 ret=0;
   ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
@@ -325,7 +355,7 @@ static uint16 make_dos_date1(time_t unixdate,struct tm *t)
 /*******************************************************************
   create a 16 bit dos packed time
 ********************************************************************/
-static uint16 make_dos_time1(time_t unixdate,struct tm *t)
+static uint16 make_dos_time1(struct tm *t)
 {
   uint16 ret=0;
   ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3));
@@ -343,9 +373,11 @@ static uint32 make_dos_date(time_t unixdate)
   uint32 ret=0;
 
   t = LocalTime(&unixdate);
+  if (!t)
+    return 0xFFFFFFFF;
 
-  ret = make_dos_date1(unixdate,t);
-  ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t);
+  ret = make_dos_date1(t);
+  ret = ((ret&0xFFFF)<<16) | make_dos_time1(t);
 
   return(ret);
 }
@@ -445,39 +477,53 @@ time_t make_unix_date2(void *date_ptr)
   ******************************************************************/
 time_t make_unix_date3(void *date_ptr)
 {
-  time_t t = IVAL(date_ptr,0);
+  time_t t = (time_t)IVAL(date_ptr,0);
   if (!null_mtime(t))
     t += LocTimeDiff(t);
   return(t);
 }
 
+
+/***************************************************************************
+return a HTTP/1.0 time string
+  ***************************************************************************/
+char *http_timestring(time_t t)
+{
+  static fstring buf;
+  struct tm *tm = LocalTime(&t);
+
+  if (!tm)
+    slprintf(buf,sizeof(buf)-1,"%ld seconds since the Epoch",(long)t);
+  else
+#ifndef HAVE_STRFTIME
+  fstrcpy(buf, asctime(tm));
+#else /* !HAVE_STRFTIME */
+  strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", tm);
+#endif /* !HAVE_STRFTIME */
+  return buf;
+}
+
+
+
 /****************************************************************************
   return the date and time as a string
 ****************************************************************************/
 char *timestring(void )
 {
-  static fstring TimeBuf;
-  time_t t = time(NULL);
-  struct tm *tm = LocalTime(&t);
-
-#ifdef NO_STRFTIME
-  fstrcpy(TimeBuf, asctime(tm));
-#elif defined(CLIX) || defined(CONVEX)
-  strftime(TimeBuf,100,"%m/%d/%Y %I:%M:%S %p",tm);
-#elif defined(AMPM)
-  strftime(TimeBuf,100,"%m/%d/%Y %r",tm);
-#elif defined(TZ_TIME)
-  {
-    int zone = TimeDiff(t);
-    int absZoneMinutes = (zone<0 ? -zone : zone) / 60;
-    size_t len = strftime(TimeBuf,sizeof(TimeBuf)-6,"%m/%d/%Y %T",tm);
-    sprintf(TimeBuf+len," %c%02d%02d",
-           zone<0?'+':'-',absZoneMinutes/60,absZoneMinutes%60);
-  }
+       static fstring TimeBuf;
+       time_t t = time(NULL);
+       struct tm *tm = LocalTime(&t);
+
+       if (!tm) {
+               slprintf(TimeBuf,sizeof(TimeBuf)-1,"%ld seconds since the Epoch",(long)t);
+       } else {
+#ifdef HAVE_STRFTIME
+               strftime(TimeBuf,100,"%Y/%m/%d %T",tm);
 #else
-  strftime(TimeBuf,100,"%m/%d/%Y %T",tm);
+               fstrcpy(TimeBuf, asctime(tm));
 #endif
-  return(TimeBuf);
+       }
+       return(TimeBuf);
 }
 
 /****************************************************************************
@@ -485,10 +531,15 @@ char *timestring(void )
   structure.
 ****************************************************************************/
 
-time_t get_create_time(struct stat *st)
+time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs)
 {
-  time_t ret = MIN(st->st_ctime, st->st_mtime);
-  time_t ret1 = MIN(ret, st->st_atime);
+  time_t ret, ret1;
+
+  if(S_ISDIR(st->st_mode) && fake_dirs)
+    return (time_t)315493200L;          /* 1/1/1980 */
+    
+  ret = MIN(st->st_ctime, st->st_mtime);
+  ret1 = MIN(ret, st->st_atime);
 
   if(ret1 != (time_t)0)
     return ret1;
@@ -500,13 +551,3 @@ time_t get_create_time(struct stat *st)
   return ret;
 }
 
-/****************************************************************************
-  return the 'access time' under UNIX from a stat structure. 
-  This function exists to allow modifications to be done depending
-  on what we want to return. Just return the normal atime (for now).
-****************************************************************************/
-    
-time_t get_access_time(struct stat *st)
-{
-  return st->st_atime;
-}