Copyright (C) Andrew Tridgell 1992-2004
Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Jeremy Allison 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#define NTTIME_INFINITY (NTTIME)0x8000000000000000LL
-/**
+/***************************************************************************
External access to time_t_min and time_t_max.
-**/
+****************************************************************************/
+
time_t get_time_t_max(void)
{
return TIME_T_MAX;
}
-/**
-a gettimeofday wrapper
-**/
+/***************************************************************************
+ A gettimeofday wrapper.
+****************************************************************************/
+
void GetTimeOfDay(struct timeval *tval)
{
#ifdef HAVE_GETTIMEOFDAY_TZ
#endif
}
-struct timespec convert_time_t_to_timespec(time_t t)
-{
- struct timespec ts;
- ts.tv_sec = t;
- ts.tv_nsec = 0;
- return ts;
-}
-
#if (SIZEOF_LONG == 8)
#define TIME_FIXUP_CONSTANT_INT 11644473600L
#elif (SIZEOF_LONG_LONG == 8)
if (t == (time_t)-1) {
*nt = (NTTIME)-1LL;
return;
- }
+ }
+
+ if (t == TIME_T_MAX) {
+ *nt = 0x7fffffffffffffffLL;
+ return;
+ }
+
if (t == 0) {
*nt = 0;
return;
*nt = t2;
}
+/****************************************************************************
+ Check if it's a null unix time.
+****************************************************************************/
-/**
-check if it's a null unix time
-**/
-BOOL null_time(time_t t)
+bool null_time(time_t t)
{
return t == 0 ||
t == (time_t)0xFFFFFFFF ||
t == (time_t)-1;
}
+/****************************************************************************
+ Check if it's a null NTTIME.
+****************************************************************************/
-/**
-check if it's a null NTTIME
-**/
-BOOL null_nttime(NTTIME t)
+bool null_nttime(NTTIME t)
{
return t == 0 || t == (NTTIME)-1;
}
+/****************************************************************************
+ Check if it's a null timespec.
+****************************************************************************/
+
+bool null_timespec(struct timespec ts)
+{
+ return ts.tv_sec == 0 ||
+ ts.tv_sec == (time_t)0xFFFFFFFF ||
+ ts.tv_sec == (time_t)-1;
+}
+
/*******************************************************************
create a 16 bit dos packed date
********************************************************************/
char *http_timestring(time_t t)
{
- static fstring buf;
+ fstring buf;
struct tm *tm = localtime(&t);
- if (!tm) {
- slprintf(buf,sizeof(buf)-1,"%ld seconds since the Epoch",(long)t);
+ if (t == TIME_T_MAX) {
+ fstrcpy(buf, "never");
+ } else if (!tm) {
+ fstr_sprintf(buf, "%ld seconds since the Epoch", (long)t);
} else {
#ifndef HAVE_STRFTIME
const char *asct = asctime(tm);
strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", tm);
#endif /* !HAVE_STRFTIME */
}
- return buf;
+ return talloc_strdup(talloc_tos(), buf);
}
/**
return True if a timeval is zero
*/
-BOOL timeval_is_zero(const struct timeval *tv)
+bool timeval_is_zero(const struct timeval *tv)
{
return tv->tv_sec == 0 && tv->tv_usec == 0;
}
/**
return True if a timer is in the past
*/
-BOOL timeval_expired(const struct timeval *tv)
+bool timeval_expired(const struct timeval *tv)
{
struct timeval tv2 = timeval_current();
if (tv2.tv_sec > tv->tv_sec) return True;
((TIME_FIXUP_CONSTANT_INT + (uint64_t)tv->tv_sec) * 1000000));
}
+/**************************************************************
+ Handle conversions between time_t and uint32, taking care to
+ preserve the "special" values.
+**************************************************************/
+
+uint32 convert_time_t_to_uint32(time_t t)
+{
+#if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
+ /* time_t is 64-bit. */
+ if (t == 0x8000000000000000LL) {
+ return 0x80000000;
+ } else if (t == 0x7FFFFFFFFFFFFFFFLL) {
+ return 0x7FFFFFFF;
+ }
+#endif
+ return (uint32)t;
+}
+
+time_t convert_uint32_to_time_t(uint32 u)
+{
+#if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
+ /* time_t is 64-bit. */
+ if (u == 0x80000000) {
+ return (time_t)0x8000000000000000LL;
+ } else if (u == 0x7FFFFFFF) {
+ return (time_t)0x7FFFFFFFFFFFFFFFLL;
+ }
+#endif
+ return (time_t)u;
+}
+
/*******************************************************************
-yield the difference between *A and *B, in seconds, ignoring leap seconds
+ Yield the difference between *A and *B, in seconds, ignoring leap seconds.
********************************************************************/
+
static int tm_diff(struct tm *a, struct tm *b)
{
int ay = a->tm_year + (1900 - 1);
int extra_time_offset=0;
-/**
- return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
- */
+/*******************************************************************
+ Return the UTC offset in seconds west of UTC, or 0 if it cannot be determined.
+********************************************************************/
+
int get_time_zone(time_t t)
{
struct tm *tm = gmtime(&t);
Check if NTTIME is 0.
****************************************************************************/
-BOOL nt_time_is_zero(const NTTIME *nt)
+bool nt_time_is_zero(const NTTIME *nt)
{
return (*nt == 0);
}
Return the date and time as a string
****************************************************************************/
-char *current_timestring(BOOL hires)
+char *current_timestring(TALLOC_CTX *ctx, bool hires)
{
- static fstring TimeBuf;
+ fstring TimeBuf;
struct timeval tp;
time_t t;
struct tm *tm;
}
#endif
}
- return(TimeBuf);
+ return talloc_strdup(ctx, TimeBuf);
}
structure.
****************************************************************************/
-time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs)
+static time_t calc_create_time(const SMB_STRUCT_STAT *st)
{
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);
return ret;
}
-struct timespec get_create_timespec(SMB_STRUCT_STAT *st,BOOL fake_dirs)
+/****************************************************************************
+ Return the 'create time' from a stat struct if it exists (birthtime) or else
+ use the best approximation.
+****************************************************************************/
+
+struct timespec get_create_timespec(const SMB_STRUCT_STAT *pst,bool fake_dirs)
{
- struct timespec ts;
- ts.tv_sec = get_create_time(st, fake_dirs);
- ts.tv_nsec = 0;
- return ts;
+ struct timespec ret;
+
+ if(S_ISDIR(pst->st_mode) && fake_dirs) {
+ ret.tv_sec = 315493200L; /* 1/1/1980 */
+ ret.tv_nsec = 0;
+ return ret;
+ }
+
+#if defined(HAVE_STAT_ST_BIRTHTIMESPEC)
+ return pst->st_birthtimespec;
+#elif defined(HAVE_STAT_ST_BIRTHTIMENSEC)
+ ret.tv_sec = pst->st_birthtime;
+ ret.tv_nsec = pst->st_birthtimenspec;
+ return ret;
+#elif defined(HAVE_STAT_ST_BIRTHTIME)
+ ret.tv_sec = pst->st_birthtime;
+ ret.tv_nsec = 0;
+ return ret;
+#else
+ ret.tv_sec = calc_create_time(pst);
+ ret.tv_nsec = 0;
+ return ret;
+#endif
}
/****************************************************************************
Get/Set all the possible time fields from a stat struct as a timespec.
****************************************************************************/
-struct timespec get_atimespec(SMB_STRUCT_STAT *pst)
+struct timespec get_atimespec(const SMB_STRUCT_STAT *pst)
{
#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
struct timespec ret;
#endif
}
-struct timespec get_mtimespec(SMB_STRUCT_STAT *pst)
+struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst)
{
#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
struct timespec ret;
#endif
}
-struct timespec get_ctimespec(SMB_STRUCT_STAT *pst)
+struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst)
{
#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
struct timespec ret;
return ts.tv_sec;
}
+struct timespec convert_time_t_to_timespec(time_t t)
+{
+ struct timespec ts;
+ ts.tv_sec = t;
+ ts.tv_nsec = 0;
+ return ts;
+}
+
+/****************************************************************************
+ Convert a normalized timeval to a timespec.
+****************************************************************************/
+
+struct timespec convert_timeval_to_timespec(const struct timeval tv)
+{
+ struct timespec ts;
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ return ts;
+}
+
+/****************************************************************************
+ Convert a normalized timespec to a timeval.
+****************************************************************************/
+
+struct timeval convert_timespec_to_timeval(const struct timespec ts)
+{
+ struct timeval tv;
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+ return tv;
+}
+
+/****************************************************************************
+ Return a timespec for the current time
+****************************************************************************/
+
+struct timespec timespec_current(void)
+{
+ struct timeval tv;
+ struct timespec ts;
+ GetTimeOfDay(&tv);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ return ts;
+}
+
+/****************************************************************************
+ Return the lesser of two timespecs.
+****************************************************************************/
+
+struct timespec timespec_min(const struct timespec *ts1,
+ const struct timespec *ts2)
+{
+ if (ts1->tv_sec < ts2->tv_sec) return *ts1;
+ if (ts1->tv_sec > ts2->tv_sec) return *ts2;
+ if (ts1->tv_nsec < ts2->tv_nsec) return *ts1;
+ return *ts2;
+}
+
+/****************************************************************************
+ compare two timespec structures.
+ Return -1 if ts1 < ts2
+ Return 0 if ts1 == ts2
+ Return 1 if ts1 > ts2
+****************************************************************************/
+
+int timespec_compare(const struct timespec *ts1, const struct timespec *ts2)
+{
+ if (ts1->tv_sec > ts2->tv_sec) return 1;
+ if (ts1->tv_sec < ts2->tv_sec) return -1;
+ if (ts1->tv_nsec > ts2->tv_nsec) return 1;
+ if (ts1->tv_nsec < ts2->tv_nsec) return -1;
+ return 0;
+}
+
/****************************************************************************
Interprets an nt time into a unix struct timespec.
Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
put_dos_date3(buf, offset, unixdate, cli->serverzone);
}
-time_t cli_make_unix_date(struct cli_state *cli, void *date_ptr)
+time_t cli_make_unix_date(struct cli_state *cli, const void *date_ptr)
{
return make_unix_date(date_ptr, cli->serverzone);
}
-time_t cli_make_unix_date2(struct cli_state *cli, void *date_ptr)
+time_t cli_make_unix_date2(struct cli_state *cli, const void *date_ptr)
{
return make_unix_date2(date_ptr, cli->serverzone);
}
-time_t cli_make_unix_date3(struct cli_state *cli, void *date_ptr)
+time_t cli_make_unix_date3(struct cli_state *cli, const void *date_ptr)
{
return make_unix_date3(date_ptr, cli->serverzone);
}
d = (int64)*nt;
/* d is now in 100ns units, since jan 1st 1601".
Save off the ns fraction. */
-
- ret.tv_nsec = (long) ((d % 100) * 100);
+
+ /*
+ * Take the last seven decimal digits and multiply by 100.
+ * to convert from 100ns units to 1ns units.
+ */
+ ret.tv_nsec = (long) ((d % (1000 * 1000 * 10)) * 100);
/* Convert to seconds */
d /= 1000*1000*10;
Check if two NTTIMEs are the same.
****************************************************************************/
-BOOL nt_time_equals(const NTTIME *nt1, const NTTIME *nt2)
+bool nt_time_equals(const NTTIME *nt1, const NTTIME *nt2)
{
return (*nt1 == *nt2);
}
d = (double)(t);
d *= 1.0e7;
- *nt = d;
+ *nt = (NTTIME)d;
/* convert to a negative value */
*nt=~*nt;
Check if it's a null mtime.
****************************************************************************/
-BOOL null_mtime(time_t mtime)
+bool null_mtime(time_t mtime)
{
if (mtime == 0 || mtime == (time_t)0xFFFFFFFF || mtime == (time_t)-1)
return(True);
and asctime fail.
****************************************************************************/
-const char *time_to_asc(const time_t *t)
+const char *time_to_asc(const time_t t)
{
const char *asct;
- struct tm *lt = localtime(t);
+ struct tm *lt = localtime(&t);
if (!lt) {
return "unknown time";
const char *display_time(NTTIME nttime)
{
- static fstring string;
-
float high;
float low;
int sec;
low = ~(nttime & 0xFFFFFFFF);
low = low/(1000*1000*10);
- sec=high+low;
+ sec=(int)(high+low);
days=sec/(60*60*24);
hours=(sec - (days*60*60*24)) / (60*60);
mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
- fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
- return (string);
+ return talloc_asprintf(talloc_tos(), "%u days, %u hours, %u minutes, "
+ "%u seconds", days, hours, mins, secs);
}
-BOOL nt_time_is_set(const NTTIME *nt)
+bool nt_time_is_set(const NTTIME *nt)
{
if (*nt == 0x7FFFFFFFFFFFFFFFLL) {
return False;
return True;
}
-