r17800: Start using struct timespec internally for file times
authorJeremy Allison <jra@samba.org>
Thu, 24 Aug 2006 16:44:00 +0000 (16:44 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:38:48 +0000 (11:38 -0500)
on the wire. This allows us to go to nsec resolution
for systems that support it. It should also now be
easy to add a correct "create time" (birth time)
for systems that support it (*BSD). I'll be watching
the build farm closely after this one for breakage :-).
Jeremy.
(This used to be commit 425280a1d23f97ef0b0be77462386d619f47b21d)

14 files changed:
source3/client/client.c
source3/client/clitar.c
source3/include/client.h
source3/lib/time.c
source3/lib/util.c
source3/libsmb/cliconnect.c
source3/libsmb/clifile.c
source3/libsmb/clifsinfo.c
source3/libsmb/clilist.c
source3/libsmb/clirap.c
source3/libsmb/libsmbclient.c
source3/smbd/nttrans.c
source3/smbd/trans2.c
source3/torture/torture.c

index 1ff63aa836363cbe561c6c9f30f45499109f41b1..385eb5a7cf55b9e01b1ce55e2bd8035151e7488a 100644 (file)
@@ -355,7 +355,7 @@ static BOOL do_this_one(file_info *finfo)
                return False;
        }
 
-       if (newer_than && finfo->mtime < newer_than) {
+       if (newer_than && finfo->mtime_ts.tv_sec < newer_than) {
                DEBUG(3,("newer_than %s failed\n", finfo->name));
                return(False);
        }
@@ -375,7 +375,7 @@ static BOOL do_this_one(file_info *finfo)
 static void display_finfo(file_info *finfo)
 {
        if (do_this_one(finfo)) {
-               time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
+               time_t t = finfo->mtime_ts.tv_sec; /* the time is assumed to be passed as GMT */
                d_printf("  %-30s%7.7s %8.0f  %s",
                         finfo->name,
                         attrib_string(finfo->mode),
index f0d0ac595c2ed716eda1c18aeae49ec5a49e58f5..87ca3245c117cc3bb518bdc5d2f51b94b5ae8b2e 100644 (file)
@@ -49,9 +49,9 @@ struct file_info_struct {
        uid_t uid;
        gid_t gid;
        /* These times are normally kept in GMT */
-       time_t mtime;
-       time_t atime;
-       time_t ctime;
+       struct timespec mtime_ts;
+       struct timespec atime_ts;
+       struct timespec ctime_ts;
        char *name;     /* This is dynamically allocate */
 
        file_info2 *next, *prev;  /* Used in the stack ... */
@@ -312,8 +312,9 @@ of link other than a GNUtar Longlink - ignoring\n"));
         * We only get the modification time of the file; set the creation time
         * from the mod. time, and the access time to current time
         */
-       finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
-       finfo->atime = time(NULL);
+       finfo->mtime_ts = finfo->ctime_ts =
+               convert_time_t_to_timespec((time_t)strtol(hb->dbuf.mtime, NULL, 8));
+       finfo->atime_ts = convert_time_t_to_timespec(time(NULL));
        finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
 
        return True;
@@ -625,18 +626,18 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                finfo.mode  = finfo1 -> mode;
                finfo.uid   = finfo1 -> uid;
                finfo.gid   = finfo1 -> gid;
-               finfo.mtime = finfo1 -> mtime;
-               finfo.atime = finfo1 -> atime;
-               finfo.ctime = finfo1 -> ctime;
+               finfo.mtime_ts = finfo1 -> mtime_ts;
+               finfo.atime_ts = finfo1 -> atime_ts;
+               finfo.ctime_ts = finfo1 -> ctime_ts;
                finfo.name  = finfo1 -> name;
        } else {
                finfo.size  = def_finfo.size;
                finfo.mode  = def_finfo.mode;
                finfo.uid   = def_finfo.uid;
                finfo.gid   = def_finfo.gid;
-               finfo.mtime = def_finfo.mtime;
-               finfo.atime = def_finfo.atime;
-               finfo.ctime = def_finfo.ctime;
+               finfo.mtime_ts = def_finfo.mtime_ts;
+               finfo.atime_ts = def_finfo.atime_ts;
+               finfo.ctime_ts = def_finfo.ctime_ts;
                finfo.name  = def_finfo.name;
        }
 
@@ -667,11 +668,14 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
 
        safe_strcpy(finfo.name,rname, strlen(rname));
        if (!finfo1) {
-               if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
+               time_t atime, mtime;
+               if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &atime, &mtime)) {
                        DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
                        return;
                }
-               finfo.ctime = finfo.mtime;
+               finfo.atime_ts = convert_time_t_to_timespec(atime);
+               finfo.mtime_ts = convert_time_t_to_timespec(mtime);
+               finfo.ctime_ts = finfo.mtime_ts;
        }
 
        DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
@@ -707,7 +711,8 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                        /* Only if the first read succeeds, write out the tar header. */
                        if (!wrote_tar_header) {
                                /* write a tar header, don't bother with mode - just set to 100644 */
-                               writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
+                               writetarheader(tarhandle, rname, finfo.size,
+                                       finfo.mtime_ts.tv_sec, "100644 \0", ftype);
                                wrote_tar_header = True;
                        }
 
@@ -836,7 +841,7 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
 
                /* write a tar directory, don't bother with mode - just set it to
                        * 40755 */
-               writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
+               writetarheader(tarhandle, cur_dir, 0, finfo->mtime_ts.tv_sec, "040755 \0", '5');
                if (tar_noisy) {
                        DEBUG(0,("                directory %s\n", cur_dir));
                }
@@ -1034,7 +1039,7 @@ static int get_file(file_info2 finfo)
        /* Now we update the creation date ... */
        DEBUG(5, ("Updating creation date on %s\n", finfo.name));
 
-       if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
+       if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec)) {
                if (tar_real_noisy) {
                        DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
                        /*return(False); */ /* Ignore, as Win95 does not allow changes */
index d11d198e1a5f592a7c79b5b4b9893a456b7aa374..a89e39d160586b1433f251bd4b3af8ae4be08a45 100644 (file)
@@ -41,9 +41,9 @@ typedef struct file_info
        uid_t uid;
        gid_t gid;
        /* these times are normally kept in GMT */
-       time_t mtime;
-       time_t atime;
-       time_t ctime;
+       struct timespec mtime_ts;
+       struct timespec atime_ts;
+       struct timespec ctime_ts;
        pstring name;
        pstring dir;
        char short_name[13*3]; /* the *3 is to cope with multi-byte */
index 0bfdfac856bca89b605136e00a2e8840c65711f7..fa4ef398f2cd978ebd6b5833dea0155d5e2fef7b 100644 (file)
@@ -172,28 +172,52 @@ int TimeDiff(time_t t)
 }
 #endif
 
+time_t convert_timespec_to_time_t(struct timespec ts)
+{
+       /* 1 ns == 1,000,000,000 - one thousand millionths of a second.
+          increment if it's greater than 500 millionth of a second. */
+       if (ts.tv_nsec > 500000000) {
+               return ts.tv_sec + 1;
+       }
+       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;
+}
+
 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
 
 /****************************************************************************
  Interpret an 8 byte "filetime" structure to a time_t
  It's originally in "100ns units since jan 1st 1601"
 
- An 8 byte value of 0xffffffffffffffff will be returned as (time_t)0.
+ An 8 byte value of 0xffffffffffffffff will be returned as a timespec of
+
+       tv_sec = 0
+       tv_nsec = 0;
 
  Returns GMT.
 ****************************************************************************/
 
-time_t nt_time_to_unix(NTTIME *nt)
+static struct timespec nt_time_to_unix_timespec(NTTIME *nt)
 {
        double d;
-       time_t ret;
+       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->high == 0xffffffff && nt->low == 0xffffffff)) {
-               return(0);
+       if ((nt->high == 0 && nt->low == 0 )||
+                       (nt->high == 0xffffffff && nt->low == 0xffffffff)) {
+               ret.tv_sec = 0;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
        d = ((double)nt->high)*4.0*(double)(1<<30);
@@ -204,15 +228,25 @@ time_t nt_time_to_unix(NTTIME *nt)
        d -= TIME_FIXUP_CONSTANT;
 
        if (d <= l_time_min) {
-               return (l_time_min);
+               ret.tv_sec = l_time_min;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
        if (d >= l_time_max) {
-               return (l_time_max);
+               ret.tv_sec = l_time_max;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
-       ret = (time_t)(d+0.5);
-       return(ret);
+       ret.tv_sec = (time_t)d;
+       ret.tv_nsec = (long) ((d - (double)ret.tv_sec)*1.0e9);
+       return ret;
+}
+
+time_t nt_time_to_unix(NTTIME *nt)
+{
+       return convert_timespec_to_time_t(nt_time_to_unix_timespec(nt));
 }
 
 /****************************************************************************
@@ -235,7 +269,7 @@ time_t nt_time_to_unix_abs(const NTTIME *nt)
        NTTIME neg_nt;
 
        if (nt->high == 0) {
-               return(0);
+               return (time_t)0;
        }
 
        if (nt->high==0x80000000 && nt->low==0) {
@@ -252,63 +286,78 @@ time_t nt_time_to_unix_abs(const NTTIME *nt)
        d *= 1.0e-7;
   
        if (!(l_time_min <= d && d <= l_time_max)) {
-               return(0);
+               return (time_t)0;
        }
 
        ret = (time_t)(d+0.5);
-
-       return(ret);
+       return ret;
 }
 
 /****************************************************************************
- Interprets an nt time into a unix time_t.
+ 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.
 ****************************************************************************/
 
-time_t interpret_long_date(char *p)
+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) {
-               return (time_t)-1;
+               struct timespec ret;
+               ret.tv_sec = (time_t)-1;
+               ret.tv_nsec = 0;
+               return ret;
        }
-       return nt_time_to_unix(&nt);
+       return nt_time_to_unix_timespec(&nt);
 }
 
 /****************************************************************************
- Put a 8 byte filetime from a time_t. Uses GMT.
+ Put a 8 byte filetime from a struct timespec. Uses GMT.
 ****************************************************************************/
 
-void unix_to_nt_time(NTTIME *nt, time_t t)
+void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts)
 {
        double d;
 
-       if (t==0) {
+       if (ts.tv_sec ==0 && ts.tv_nsec == 0) {
                nt->low = 0;
                nt->high = 0;
                return;
        }
-       if (t == TIME_T_MAX) {
+       if (ts.tv_sec == TIME_T_MAX) {
                nt->low = 0xffffffff;
                nt->high = 0x7fffffff;
                return;
        }               
-       if (t == (time_t)-1) {
+       if (ts.tv_sec == (time_t)-1) {
                nt->low = 0xffffffff;
                nt->high = 0xffffffff;
                return;
        }               
 
-       d = (double)(t);
+       d = (double)(ts.tv_sec);
        d += TIME_FIXUP_CONSTANT;
        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));
 }
 
+/****************************************************************************
+ Put a 8 byte filetime from a time_t. Uses GMT.
+****************************************************************************/
+
+void unix_to_nt_time(NTTIME *nt, time_t t)
+{
+       struct timespec ts;
+       ts.tv_sec = t;
+       ts.tv_nsec = 0;
+       unix_timespec_to_nt_time(nt, ts);
+}
+
 /****************************************************************************
  Convert a time_t to a NTTIME structure
 
@@ -356,14 +405,22 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t)
  pointed to by p.
 ****************************************************************************/
 
-void put_long_date(char *p, time_t t)
+void put_long_date_timespec(char *p, struct timespec ts)
 {
        NTTIME nt;
-       unix_to_nt_time(&nt, t);
+       unix_timespec_to_nt_time(&nt, ts);
        SIVAL(p, 0, nt.low);
        SIVAL(p, 4, nt.high);
 }
 
+void put_long_date(char *p, time_t t)
+{
+       struct timespec ts;
+       ts.tv_sec = t;
+       ts.tv_nsec = 0;
+       put_long_date_timespec(p, ts);
+}
+
 /****************************************************************************
  Check if it's a null mtime.
 ****************************************************************************/
@@ -717,6 +774,14 @@ time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs)
        return ret;
 }
 
+struct timespec get_create_timespec(SMB_STRUCT_STAT *st,BOOL fake_dirs)
+{
+       struct timespec ts;
+       ts.tv_sec = get_create_time(st, fake_dirs);
+       ts.tv_nsec = 0;
+       return ts;
+}
+
 /****************************************************************************
  Initialise an NTTIME to -1, which means "unknown" or "don't expire".
 ****************************************************************************/
@@ -955,7 +1020,7 @@ time_t generalized_to_unix_time(const char *str)
 }
 
 /****************************************************************************
Return all the possible time fields from a stat struct as a timespec.
Get/Set all the possible time fields from a stat struct as a timespec.
 ****************************************************************************/
 
 struct timespec get_atimespec(SMB_STRUCT_STAT *pst)
@@ -981,6 +1046,23 @@ struct timespec get_atimespec(SMB_STRUCT_STAT *pst)
 #endif
 }
 
+void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+       /* Old system - no ns timestamp. */
+       pst->st_atime = ts.tv_sec;
+#else
+#if defined(HAVE_STAT_ST_ATIM)
+       pst->st_atim = ts;
+#elif defined(HAVE_STAT_ST_ATIMENSEC)
+       pst->st_atime = ts.tv_sec;
+       pst->st_atimensec = ts.tv_nsec
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT 
+#endif
+#endif
+}
+
 struct timespec get_mtimespec(SMB_STRUCT_STAT *pst)
 {
 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
@@ -1004,6 +1086,23 @@ struct timespec get_mtimespec(SMB_STRUCT_STAT *pst)
 #endif
 }
 
+void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+       /* Old system - no ns timestamp. */
+       pst->st_mtime = ts.tv_sec;
+#else
+#if defined(HAVE_STAT_ST_MTIM)
+       pst->st_mtim = ts;
+#elif defined(HAVE_STAT_ST_MTIMENSEC)
+       pst->st_mtime = ts.tv_sec;
+       pst->st_mtimensec = ts.tv_nsec
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT 
+#endif
+#endif
+}
+
 struct timespec get_ctimespec(SMB_STRUCT_STAT *pst)
 {
 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
@@ -1027,6 +1126,23 @@ struct timespec get_ctimespec(SMB_STRUCT_STAT *pst)
 #endif
 }
 
+void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+       /* Old system - no ns timestamp. */
+       pst->st_ctime = ts.tv_sec;
+#else
+#if defined(HAVE_STAT_ST_CTIM)
+       pst->st_atim = ts;
+#elif defined(HAVE_STAT_ST_CTIMENSEC)
+       pst->st_ctime = ts.tv_sec;
+       pst->st_ctimensec = ts.tv_nsec
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT 
+#endif
+#endif
+}
+
 #if 0
 /****************************************************************************
  Return the best approximation to a 'create time' under UNIX from a stat
@@ -1056,6 +1172,11 @@ struct timespec get_create_timespec(SMB_STRUCT_STAT *st,BOOL fake_dirs)
 }
 #endif
 
+void dos_filetime_timespec(struct timespec *tsp)
+{
+       tsp->tv_sec &= ~1;
+       tsp->tv_nsec = 0;
+}
 
 /**
  Return the date and time as a string
index ef954015d66e7e463943949064cae51f7622cc88..20ff4514a02e8e81daa9654725ea4169db17f694 100644 (file)
@@ -61,7 +61,7 @@ extern fstring remote_arch;
 enum protocol_types Protocol = PROTOCOL_COREPLUS;
 
 /* a default finfo structure to ensure all fields are sensible */
-file_info def_finfo = {-1,0,0,0,0,0,0,"",""};
+file_info def_finfo;
 
 /* this is used by the chaining code */
 int chain_size = 0;
index 3e4b6f05453d79e7f3900c133b30fc64d61a90ce..0e179416dc7c596e9c65e91f8345a7dc7519655c 100644 (file)
@@ -1149,6 +1149,7 @@ BOOL cli_negprot(struct cli_state *cli)
        }
 
        if (cli->protocol >= PROTOCOL_NT1) {    
+               struct timespec ts;
                /* NT protocol */
                cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
                cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
@@ -1157,7 +1158,8 @@ BOOL cli_negprot(struct cli_state *cli)
                cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
                cli->serverzone *= 60;
                /* this time arrives in real GMT */
-               cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
+               ts = interpret_long_date(cli->inbuf+smb_vwv11+1);
+               cli->servertime = ts.tv_sec;
                cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
                cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
                if (cli->capabilities & CAP_RAW_MODE) {
index 9beafc55fb0443e9c6e84d478b14e7ebdc0c4e23..fb07dae427dbf846a41d150388d5a151be352ae5 100644 (file)
@@ -266,9 +266,10 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu
        /* assume 512 byte blocks */
        sbuf->st_blocks /= 512;
 #endif
-       sbuf->st_ctime = interpret_long_date(rdata + 16);    /* time of last change */
-       sbuf->st_atime = interpret_long_date(rdata + 24);    /* time of last access */
-       sbuf->st_mtime = interpret_long_date(rdata + 32);    /* time of last modification */
+       set_ctimespec(sbuf, interpret_long_date(rdata + 16));    /* time of last change */
+       set_atimespec(sbuf, interpret_long_date(rdata + 24));    /* time of last access */
+       set_mtimespec(sbuf, interpret_long_date(rdata + 32));    /* time of last modification */
+
        sbuf->st_uid = (uid_t) IVAL(rdata,40);      /* user ID of owner */
        sbuf->st_gid = (gid_t) IVAL(rdata,48);      /* group ID of owner */
        sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
index c6aa6a70a031470c4b56ae66d7d2a26d8bba0f47..9c3b6e3aed328ca9c504148ee62793cceb35a532 100644 (file)
@@ -282,7 +282,9 @@ BOOL cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *
        }
 
        if (pdate) {
-               *pdate = interpret_long_date(rdata);
+               struct timespec ts;
+               ts = interpret_long_date(rdata);
+               *pdate = ts.tv_sec;
        }
        if (pserial_number) {
                *pserial_number = IVAL(rdata,8);
index b022a107d09822c53781e2a5f5f71bca498af5fe..18c058f9dfbd44d437ffddf55cf30f4f38752aea 100644 (file)
@@ -49,9 +49,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f
                case 1: /* OS/2 understands this */
                        /* these dates are converted to GMT by
                            make_unix_date */
-                       finfo->ctime = cli_make_unix_date2(cli, p+4);
-                       finfo->atime = cli_make_unix_date2(cli, p+8);
-                       finfo->mtime = cli_make_unix_date2(cli, p+12);
+                       finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4));
+                       finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8));
+                       finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12));
                        finfo->size = IVAL(p,16);
                        finfo->mode = CVAL(p,24);
                        len = CVAL(p, 26);
@@ -70,9 +70,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f
                case 2: /* this is what OS/2 uses mostly */
                        /* these dates are converted to GMT by
                            make_unix_date */
-                       finfo->ctime = cli_make_unix_date2(cli, p+4);
-                       finfo->atime = cli_make_unix_date2(cli, p+8);
-                       finfo->mtime = cli_make_unix_date2(cli, p+12);
+                       finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4));
+                       finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8));
+                       finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12));
                        finfo->size = IVAL(p,16);
                        finfo->mode = CVAL(p,24);
                        len = CVAL(p, 30);
@@ -96,11 +96,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f
                                
                        /* Offset zero is "create time", not "change time". */
                        p += 8;
-                       finfo->atime = interpret_long_date(p);
+                       finfo->atime_ts = interpret_long_date(p);
                        p += 8;
-                       finfo->mtime = interpret_long_date(p);
+                       finfo->mtime_ts = interpret_long_date(p);
                        p += 8;
-                       finfo->ctime = interpret_long_date(p);
+                       finfo->ctime_ts = interpret_long_date(p);
                        p += 8;
                        finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
                        p += 8;
@@ -373,8 +373,10 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi
        finfo->mode = CVAL(p,21);
        
        /* this date is converted to GMT by make_unix_date */
-       finfo->ctime = cli_make_unix_date(cli, p+22);
-       finfo->mtime = finfo->atime = finfo->ctime;
+       finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22);
+       finfo->ctime_ts.tv_nsec = 0;
+       finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec;
+       finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0;
        finfo->size = IVAL(p,26);
        clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII);
        if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) {
index 1227b26b2ffa9f52c7bcd64dd05f8357cc312758..677c8f1fc3d7a9cb222f99b562672c6e2a25925a 100644 (file)
@@ -555,8 +555,8 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
 ****************************************************************************/
 
 BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, 
-                   time_t *create_time, time_t *access_time, time_t *write_time, 
-                   time_t *change_time, SMB_OFF_T *size, uint16 *mode,
+                   struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, 
+                   struct timespec *change_time, SMB_OFF_T *size, uint16 *mode,
                    SMB_INO_T *ino)
 {
        unsigned int data_len = 0;
@@ -670,8 +670,8 @@ send a qfileinfo call
 ****************************************************************************/
 BOOL cli_qfileinfo(struct cli_state *cli, int fnum, 
                   uint16 *mode, SMB_OFF_T *size,
-                  time_t *create_time, time_t *access_time, time_t *write_time, 
-                  time_t *change_time, SMB_INO_T *ino)
+                  struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, 
+                  struct timespec *change_time, SMB_INO_T *ino)
 {
        unsigned int data_len = 0;
        unsigned int param_len = 0;
@@ -794,9 +794,9 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name,
                return False;
        }
 
-       sbuf->st_atime = interpret_long_date( rdata+8 ); /* Access time. */
-       sbuf->st_mtime = interpret_long_date( rdata+16 ); /* Write time. */
-       sbuf->st_ctime = interpret_long_date( rdata+24 ); /* Change time. */
+       set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */
+       set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */
+       set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */
        
        *attributes = IVAL( rdata, 32 );
        
index abeb66b3733169fbea28e0a3dd3bedf5399eaf95..2656bd0f04600d9b0627eb9d4f6feabae7781176 100644 (file)
@@ -1470,14 +1470,15 @@ smbc_getatr(SMBCCTX * context,
             char *path, 
             uint16 *mode,
             SMB_OFF_T *size, 
-            time_t *c_time,
-            time_t *a_time,
-            time_t *m_time,
+            struct timespec *c_time_ts,
+            struct timespec *a_time_ts,
+            struct timespec *m_time_ts,
             SMB_INO_T *ino)
 {
        pstring fixedpath;
        pstring targetpath;
        struct cli_state *targetcli;
+       time_t m_time;
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
@@ -1514,7 +1515,7 @@ smbc_getatr(SMBCCTX * context,
   
        if (!srv->no_pathinfo2 &&
             cli_qpathinfo2(targetcli, targetpath,
-                           NULL, a_time, m_time, c_time, size, mode, ino)) {
+                           NULL, a_time_ts, m_time_ts, c_time_ts, size, mode, ino)) {
             return True;
         }
 
@@ -1524,10 +1525,11 @@ smbc_getatr(SMBCCTX * context,
                 return False;
         }
 
-       if (cli_getatr(targetcli, targetpath, mode, size, m_time)) {
-                if (m_time != NULL) {
-                        if (a_time != NULL) *a_time = *m_time;
-                        if (c_time != NULL) *c_time = *m_time;
+       if (cli_getatr(targetcli, targetpath, mode, size, &m_time)) {
+                if (m_time_ts != NULL) {
+                       *m_time_ts = convert_time_t_to_timespec(m_time);
+                        if (a_time_ts != NULL) *a_time_ts = *m_time_ts;
+                        if (c_time_ts != NULL) *c_time_ts = *m_time_ts;
                 }
                srv->no_pathinfo2 = True;
                return True;
@@ -1709,11 +1711,11 @@ smbc_unlink_ctx(SMBCCTX *context,
                        int saverr = errno;
                        SMB_OFF_T size = 0;
                        uint16 mode = 0;
-                       time_t m_time = 0, a_time = 0, c_time = 0;
+                       struct timespec m_time_ts, a_time_ts, c_time_ts;
                        SMB_INO_T ino = 0;
 
                        if (!smbc_getatr(context, srv, path, &mode, &size,
-                                        &c_time, &a_time, &m_time, &ino)) {
+                                        &c_time_ts, &a_time_ts, &m_time_ts, &ino)) {
 
                                /* Hmmm, bad error ... What? */
 
@@ -2049,9 +2051,9 @@ smbc_stat_ctx(SMBCCTX *context,
         fstring password;
         fstring workgroup;
        pstring path;
-       time_t m_time = 0;
-        time_t a_time = 0;
-        time_t c_time = 0;
+       struct timespec m_time_ts;
+        struct timespec a_time_ts;
+        struct timespec c_time_ts;
        SMB_OFF_T size = 0;
        uint16 mode = 0;
        SMB_INO_T ino = 0;
@@ -2095,7 +2097,7 @@ smbc_stat_ctx(SMBCCTX *context,
        }
 
        if (!smbc_getatr(context, srv, path, &mode, &size, 
-                        &c_time, &a_time, &m_time, &ino)) {
+                        &c_time_ts, &a_time_ts, &m_time_ts, &ino)) {
 
                errno = smbc_errno(context, srv->cli);
                return -1;
@@ -2106,9 +2108,9 @@ smbc_stat_ctx(SMBCCTX *context,
 
        smbc_setup_stat(context, st, path, size, mode);
 
-       st->st_atime = a_time;
-       st->st_ctime = c_time;
-       st->st_mtime = m_time;
+       set_atimespec(st, a_time_ts);
+       set_ctimespec(st, c_time_ts);
+       set_mtimespec(st, m_time_ts);
        st->st_dev   = srv->dev;
 
        return 0;
@@ -2124,9 +2126,9 @@ smbc_fstat_ctx(SMBCCTX *context,
                SMBCFILE *file,
                struct stat *st)
 {
-       time_t c_time;
-        time_t a_time;
-        time_t m_time;
+       struct timespec c_time_ts;
+        struct timespec a_time_ts;
+        struct timespec m_time_ts;
        SMB_OFF_T size;
        uint16 mode;
        fstring server;
@@ -2182,22 +2184,26 @@ smbc_fstat_ctx(SMBCCTX *context,
        /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
 
        if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,
-                           NULL, &a_time, &m_time, &c_time, &ino)) {
-           if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
-                              &c_time, &a_time, &m_time)) {
+                           NULL, &a_time_ts, &m_time_ts, &c_time_ts, &ino)) {
+               time_t c_time, a_time, m_time;
+               if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
+                               &c_time, &a_time, &m_time)) {
 
-               errno = EINVAL;
-               return -1;
-           }
+                       errno = EINVAL;
+                       return -1;
+               }
+               c_time_ts = convert_time_t_to_timespec(c_time);
+               a_time_ts = convert_time_t_to_timespec(a_time);
+               m_time_ts = convert_time_t_to_timespec(m_time);
        }
 
        st->st_ino = ino;
 
        smbc_setup_stat(context, st, file->fname, size, mode);
 
-       st->st_atime = a_time;
-       st->st_ctime = c_time;
-       st->st_mtime = m_time;
+       set_atimespec(st, a_time_ts);
+       set_ctimespec(st, c_time_ts);
+       set_mtimespec(st, m_time_ts);
        st->st_dev = file->srv->dev;
 
        return 0;
@@ -4079,7 +4085,7 @@ dos_attr_query(SMBCCTX *context,
                const char *filename,
                SMBCSRV *srv)
 {
-        time_t m_time = 0, a_time = 0, c_time = 0;
+       struct timespec m_time_ts, a_time_ts, c_time_ts;
         SMB_OFF_T size = 0;
         uint16 mode = 0;
        SMB_INO_T inode = 0;
@@ -4094,7 +4100,7 @@ dos_attr_query(SMBCCTX *context,
         /* Obtain the DOS attributes */
         if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename),
                          &mode, &size, 
-                         &c_time, &a_time, &m_time, &inode)) {
+                         &c_time_ts, &a_time_ts, &m_time_ts, &inode)) {
         
                 errno = smbc_errno(context, srv->cli);
                 DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
@@ -4104,9 +4110,9 @@ dos_attr_query(SMBCCTX *context,
                 
         ret->mode = mode;
         ret->size = size;
-        ret->a_time = a_time;
-        ret->c_time = c_time;
-        ret->m_time = m_time;
+        ret->a_time = convert_timespec_to_time_t(a_time_ts);
+        ret->c_time = convert_timespec_to_time_t(c_time_ts);
+        ret->m_time = convert_timespec_to_time_t(m_time_ts);
         ret->inode = inode;
 
         return ret;
@@ -4200,7 +4206,8 @@ cacl_get(SMBCCTX *context,
         char *name;
         char *pExclude;
         char *p;
-       time_t m_time = 0, a_time = 0, c_time = 0;
+       struct timespec m_time_ts, a_time_ts, c_time_ts;
+       time_t m_time = (time_t)0, a_time = (time_t)0, c_time = (time_t)0;
        SMB_OFF_T size = 0;
        uint16 mode = 0;
        SMB_INO_T ino = 0;
@@ -4547,13 +4554,16 @@ cacl_get(SMBCCTX *context,
 
                 /* Obtain the DOS attributes */
                 if (!smbc_getatr(context, srv, filename, &mode, &size, 
-                                 &c_time, &a_time, &m_time, &ino)) {
+                                 &c_time_ts, &a_time_ts, &m_time_ts, &ino)) {
                         
                         errno = smbc_errno(context, srv->cli);
                         return -1;
                         
                 }
-                
+                c_time = convert_timespec_to_time_t(c_time_ts);
+                a_time = convert_timespec_to_time_t(a_time_ts);
+                m_time = convert_timespec_to_time_t(m_time_ts);
+
                 if (! exclude_dos_mode) {
                         if (all || all_dos) {
                                 if (determine_size) {
index d107bf84d360208019ac47f1af2a22ba48de16f2..4dcc807c30c5974f84f1086c902378081df580ec 100644 (file)
@@ -435,31 +435,6 @@ int reply_ntcreate_and_X_quota(connection_struct *conn,
        /* SCVAL(p,0,NO_OPLOCK_RETURN); */
        p++;
        SSVAL(p,0,fsp->fnum);
-#if 0
-       p += 2;
-       SIVAL(p,0,smb_action);
-       p += 4;
-       
-       /* Create time. */  
-       put_long_date(p,c_time);
-       p += 8;
-       put_long_date(p,sbuf.st_atime); /* access time */
-       p += 8;
-       put_long_date(p,sbuf.st_mtime); /* write time */
-       p += 8;
-       put_long_date(p,sbuf.st_mtime); /* change time */
-       p += 8;
-       SIVAL(p,0,fattr); /* File Attributes. */
-       p += 4;
-       SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
-       p += 8;
-       SOFF_T(p,0,file_len);
-       p += 8;
-       if (flags & EXTENDED_RESPONSE_REQUIRED)
-               SSVAL(p,2,0x7);
-       p += 4;
-       SCVAL(p,0,fsp->is_directory ? 1 : 0);
-#endif
 
        DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
 
@@ -493,7 +468,9 @@ int reply_ntcreate_and_X(connection_struct *conn,
        BOOL bad_path = False;
        files_struct *fsp=NULL;
        char *p = NULL;
-       time_t c_time;
+       struct timespec c_timespec;
+       struct timespec a_timespec;
+       struct timespec m_timespec;
        BOOL extended_oplock_granted = False;
        NTSTATUS status;
 
@@ -884,22 +861,23 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
        p += 4;
        
        /* Create time. */  
-       c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       a_timespec = get_atimespec(&sbuf);
+       m_timespec = get_mtimespec(&sbuf);
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
-               c_time &= ~1;
-               sbuf.st_atime &= ~1;
-               sbuf.st_mtime &= ~1;
-               sbuf.st_mtime &= ~1;
+               dos_filetime_timespec(&c_timespec);
+               dos_filetime_timespec(&a_timespec);
+               dos_filetime_timespec(&m_timespec);
        }
 
-       put_long_date(p,c_time);
+       put_long_date_timespec(p, c_timespec);
        p += 8;
-       put_long_date(p,sbuf.st_atime); /* access time */
+       put_long_date_timespec(p, a_timespec); /* access time */
        p += 8;
-       put_long_date(p,sbuf.st_mtime); /* write time */
+       put_long_date_timespec(p, m_timespec); /* write time */
        p += 8;
-       put_long_date(p,sbuf.st_mtime); /* change time */
+       put_long_date_timespec(p, m_timespec); /* change time */
        p += 8;
        SIVAL(p,0,fattr); /* File Attributes. */
        p += 4;
@@ -1119,7 +1097,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        uint32 sd_len;
        uint32 ea_len;
        uint16 root_dir_fid;
-       time_t c_time;
+       struct timespec c_timespec;
+       struct timespec a_timespec;
+       struct timespec m_timespec;
        struct ea_list *ea_list = NULL;
        TALLOC_CTX *ctx = NULL;
        char *pdata = NULL;
@@ -1518,22 +1498,23 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        p += 8;
 
        /* Create time. */
-       c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       a_timespec = get_atimespec(&sbuf);
+       m_timespec = get_mtimespec(&sbuf);
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
-               c_time &= ~1;
-               sbuf.st_atime &= ~1;
-               sbuf.st_mtime &= ~1;
-               sbuf.st_mtime &= ~1;
+               dos_filetime_timespec(&c_timespec);
+               dos_filetime_timespec(&a_timespec);
+               dos_filetime_timespec(&m_timespec);
        }
 
-       put_long_date(p,c_time);
+       put_long_date_timespec(p, c_timespec); /* create time. */
        p += 8;
-       put_long_date(p,sbuf.st_atime); /* access time */
+       put_long_date_timespec(p, a_timespec); /* access time */
        p += 8;
-       put_long_date(p,sbuf.st_mtime); /* write time */
+       put_long_date_timespec(p, m_timespec); /* write time */
        p += 8;
-       put_long_date(p,sbuf.st_mtime); /* change time */
+       put_long_date_timespec(p, m_timespec); /* change time */
        p += 8;
        SIVAL(p,0,fattr); /* File Attributes. */
        p += 4;
index b4799d83cce73a4455047261b3c0b1a626c11c8f..87bfa18dcfe773ea66157d681b3d61b56690bae0 100644 (file)
@@ -1077,7 +1077,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
        SMB_OFF_T file_size = 0;
        SMB_BIG_UINT allocation_size = 0;
        uint32 len;
-       time_t mdate=0, adate=0, cdate=0;
+       struct timespec mdate_ts, adate_ts, create_date_ts;
+       time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
        char *nameptr;
        char *last_entry_ptr;
        BOOL was_8_3;
@@ -1089,6 +1090,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
        *out_of_space = False;
        *got_exact_match = False;
 
+       ZERO_STRUCT(mdate_ts);
+       ZERO_STRUCT(adate_ts);
+       ZERO_STRUCT(create_date_ts);
+
        if (!conn->dirptr)
                return(False);
 
@@ -1197,17 +1202,21 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        if (!(mode & aDIR))
                                file_size = get_file_size(sbuf);
                        allocation_size = get_allocation_size(conn,NULL,&sbuf);
-                       mdate = sbuf.st_mtime;
-                       adate = sbuf.st_atime;
-                       cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+
+                       mdate_ts = get_mtimespec(&sbuf);
+                       adate_ts = get_atimespec(&sbuf);
+                       create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
 
                        if (lp_dos_filetime_resolution(SNUM(conn))) {
-                               cdate &= ~1;
-                               mdate &= ~1;
-                               adate &= ~1;
+                               dos_filetime_timespec(&create_date_ts);
+                               dos_filetime_timespec(&mdate_ts);
+                               dos_filetime_timespec(&adate_ts);
                        }
 
-
+                       create_date = convert_timespec_to_time_t(create_date_ts);
+                       mdate = convert_timespec_to_time_t(mdate_ts);
+                       adate = convert_timespec_to_time_t(adate_ts);
+                       
                        DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
          
                        found = True;
@@ -1230,7 +1239,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                                SIVAL(p,0,reskey);
                                p += 4;
                        }
-                       srv_put_dos_date2(p,0,cdate);
+                       srv_put_dos_date2(p,0,create_date);
                        srv_put_dos_date2(p,4,adate);
                        srv_put_dos_date2(p,8,mdate);
                        SIVAL(p,12,(uint32)file_size);
@@ -1262,7 +1271,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                                SIVAL(p,0,reskey);
                                p += 4;
                        }
-                       srv_put_dos_date2(p,0,cdate);
+                       srv_put_dos_date2(p,0,create_date);
                        srv_put_dos_date2(p,4,adate);
                        srv_put_dos_date2(p,8,mdate);
                        SIVAL(p,12,(uint32)file_size);
@@ -1306,7 +1315,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                                SIVAL(p,0,reskey);
                                p += 4;
                        }
-                       srv_put_dos_date2(p,0,cdate);
+                       srv_put_dos_date2(p,0,create_date);
                        srv_put_dos_date2(p,4,adate);
                        srv_put_dos_date2(p,8,mdate);
                        SIVAL(p,12,(uint32)file_size);
@@ -1355,10 +1364,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        was_8_3 = mangle_is_8_3(fname, True, conn->params);
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date(p,cdate); p += 8;
-                       put_long_date(p,adate); p += 8;
-                       put_long_date(p,mdate); p += 8;
-                       put_long_date(p,mdate); p += 8;
+                       put_long_date_timespec(p,create_date_ts); p += 8;
+                       put_long_date_timespec(p,adate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1401,10 +1410,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date(p,cdate); p += 8;
-                       put_long_date(p,adate); p += 8;
-                       put_long_date(p,mdate); p += 8;
-                       put_long_date(p,mdate); p += 8;
+                       put_long_date_timespec(p,create_date_ts); p += 8;
+                       put_long_date_timespec(p,adate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1422,10 +1431,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date(p,cdate); p += 8;
-                       put_long_date(p,adate); p += 8;
-                       put_long_date(p,mdate); p += 8;
-                       put_long_date(p,mdate); p += 8;
+                       put_long_date_timespec(p,create_date_ts); p += 8;
+                       put_long_date_timespec(p,adate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1467,10 +1476,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date(p,cdate); p += 8;
-                       put_long_date(p,adate); p += 8;
-                       put_long_date(p,mdate); p += 8;
-                       put_long_date(p,mdate); p += 8;
+                       put_long_date_timespec(p,create_date_ts); p += 8;
+                       put_long_date_timespec(p,adate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1498,10 +1507,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        was_8_3 = mangle_is_8_3(fname, True, conn->params);
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date(p,cdate); p += 8;
-                       put_long_date(p,adate); p += 8;
-                       put_long_date(p,mdate); p += 8;
-                       put_long_date(p,mdate); p += 8;
+                       put_long_date_timespec(p,create_date_ts); p += 8;
+                       put_long_date_timespec(p,adate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(p,mdate_ts); p += 8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1558,9 +1567,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
                        p+= 8;
 
-                       put_long_date(p,sbuf.st_ctime);       /* Inode change Time 64 Bit */
-                       put_long_date(p+8,sbuf.st_atime);     /* Last access time 64 Bit */
-                       put_long_date(p+16,sbuf.st_mtime);    /* Last modification time 64 Bit */
+                       put_long_date_timespec(p,get_ctimespec(&sbuf));       /* Inode change Time 64 Bit */
+                       put_long_date_timespec(p+8,get_atimespec(&sbuf));     /* Last access time 64 Bit */
+                       put_long_date_timespec(p+16,get_mtimespec(&sbuf));    /* Last modification time 64 Bit */
                        p+= 24;
 
                        SIVAL(p,0,sbuf.st_uid);               /* user id for the owner */
@@ -2839,7 +2848,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
        BOOL bad_path = False;
        BOOL delete_pending = False;
        int len;
-       time_t c_time;
+       time_t create_time, mtime, atime;
+       struct timespec create_time_ts, mtime_ts, atime_ts;
        files_struct *fsp = NULL;
        TALLOC_CTX *data_ctx = NULL;
        struct ea_list *ea_list = NULL;
@@ -3058,21 +3068,25 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        }
        pdata = *ppdata;
 
-       c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       mtime_ts = get_mtimespec(&sbuf);
+       atime_ts = get_atimespec(&sbuf);
 
        allocation_size = get_allocation_size(conn,fsp,&sbuf);
 
        if (fsp) {
                if (fsp->pending_modtime) {
                        /* the pending modtime overrides the current modtime */
-                       sbuf.st_mtime = fsp->pending_modtime;
+                       mtime_ts.tv_sec = fsp->pending_modtime;
+                       mtime_ts.tv_nsec = 0;
                }
        } else {
                /* Do we have this path open ? */
                files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
                if (fsp1 && fsp1->pending_modtime) {
                        /* the pending modtime overrides the current modtime */
-                       sbuf.st_mtime = fsp1->pending_modtime;
+                       mtime_ts.tv_sec = fsp->pending_modtime;
+                       mtime_ts.tv_nsec = 0;
                }
                if (fsp1 && fsp1->initial_allocation_size) {
                        allocation_size = get_allocation_size(conn, fsp1, &sbuf);
@@ -3080,12 +3094,15 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        }
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
-               c_time &= ~1;
-               sbuf.st_atime &= ~1;
-               sbuf.st_ctime &= ~1;
-               sbuf.st_mtime &= ~1;
+               dos_filetime_timespec(&create_time_ts);
+               dos_filetime_timespec(&mtime_ts);
+               dos_filetime_timespec(&atime_ts);
        }
 
+       create_time = convert_timespec_to_time_t(create_time_ts);
+       mtime = convert_timespec_to_time_t(mtime_ts);
+       atime = convert_timespec_to_time_t(atime_ts);
+
        /* NT expects the name to be in an exact form of the *full*
           filename. See the trans2 torture test */
        if (strequal(base_name,".")) {
@@ -3099,9 +3116,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                case SMB_INFO_STANDARD:
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
                        data_size = 22;
-                       srv_put_dos_date2(pdata,l1_fdateCreation,c_time);
-                       srv_put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
-                       srv_put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
+                       srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
+                       srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
+                       srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
                        SIVAL(pdata,l1_cbFile,(uint32)file_size);
                        SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
                        SSVAL(pdata,l1_attrFile,mode);
@@ -3112,9 +3129,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
                        data_size = 26;
-                       srv_put_dos_date2(pdata,0,c_time);
-                       srv_put_dos_date2(pdata,4,sbuf.st_atime);
-                       srv_put_dos_date2(pdata,8,sbuf.st_mtime); /* write time */
+                       srv_put_dos_date2(pdata,0,create_time);
+                       srv_put_dos_date2(pdata,4,atime);
+                       srv_put_dos_date2(pdata,8,mtime); /* write time */
                        SIVAL(pdata,12,(uint32)file_size);
                        SIVAL(pdata,16,(uint32)allocation_size);
                        SSVAL(pdata,20,mode);
@@ -3190,20 +3207,17 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                data_size = 40;
                                SIVAL(pdata,36,0);
                        }
-                       put_long_date(pdata,c_time);
-                       put_long_date(pdata+8,sbuf.st_atime);
-                       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
-                       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+                       put_long_date_timespec(pdata,create_time_ts);
+                       put_long_date_timespec(pdata+8,atime_ts);
+                       put_long_date_timespec(pdata+16,mtime_ts); /* write time */
+                       put_long_date_timespec(pdata+24,mtime_ts); /* change time */
                        SIVAL(pdata,32,mode);
 
                        DEBUG(5,("SMB_QFBI - "));
-                       {
-                               time_t create_time = c_time;
-                               DEBUG(5,("create: %s ", ctime(&create_time)));
-                       }
-                       DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
-                       DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
-                       DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
+                       DEBUG(5,("create: %s ", ctime(&create_time)));
+                       DEBUG(5,("access: %s ", ctime(&atime)));
+                       DEBUG(5,("write: %s ", ctime(&mtime)));
+                       DEBUG(5,("change: %s ", ctime(&mtime)));
                        DEBUG(5,("mode: %x\n", mode));
                        break;
 
@@ -3277,10 +3291,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                {
                        unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
-                       put_long_date(pdata,c_time);
-                       put_long_date(pdata+8,sbuf.st_atime);
-                       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
-                       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+                       put_long_date_timespec(pdata,create_time_ts);
+                       put_long_date_timespec(pdata+8,atime_ts);
+                       put_long_date_timespec(pdata+16,mtime_ts); /* write time */
+                       put_long_date_timespec(pdata+24,mtime_ts); /* change time */
                        SIVAL(pdata,32,mode);
                        SIVAL(pdata,36,0); /* padding. */
                        pdata += 40;
@@ -3387,10 +3401,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
                case SMB_FILE_NETWORK_OPEN_INFORMATION:
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
-                       put_long_date(pdata,c_time);
-                       put_long_date(pdata+8,sbuf.st_atime);
-                       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
-                       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+                       put_long_date_timespec(pdata,create_time_ts);
+                       put_long_date_timespec(pdata+8,atime_ts);
+                       put_long_date_timespec(pdata+16,mtime_ts); /* write time */
+                       put_long_date_timespec(pdata+24,mtime_ts); /* change time */
                        SIVAL(pdata,32,allocation_size);
                        SOFF_T(pdata,40,file_size);
                        SIVAL(pdata,48,mode);
@@ -3420,9 +3434,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
                        pdata += 8;
 
-                       put_long_date(pdata,sbuf.st_ctime);       /* Creation Time 64 Bit */
-                       put_long_date(pdata+8,sbuf.st_atime);     /* Last access time 64 Bit */
-                       put_long_date(pdata+16,sbuf.st_mtime);    /* Last modification time 64 Bit */
+                       put_long_date_timespec(pdata,get_ctimespec(&sbuf));       /* Creation Time 64 Bit */
+                       put_long_date_timespec(pdata+8,get_atimespec(&sbuf));     /* Last access time 64 Bit */
+                       put_long_date_timespec(pdata+16,get_mtimespec(&sbuf));    /* Last modification time 64 Bit */
                        pdata += 24;
 
                        SIVAL(pdata,0,sbuf.st_uid);               /* user id for the owner */
@@ -3983,10 +3997,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                        /* Ignore create time at offset pdata. */
 
                        /* access time */
-                       tvs.actime = interpret_long_date(pdata+8);
+                       tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+8));
 
-                       write_time = interpret_long_date(pdata+16);
-                       changed_time = interpret_long_date(pdata+24);
+                       write_time = convert_timespec_to_time_t(interpret_long_date(pdata+16));
+                       changed_time = convert_timespec_to_time_t(interpret_long_date(pdata+24));
 
                        tvs.modtime = MIN(write_time, changed_time);
 
@@ -4212,8 +4226,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
 #endif /* LARGE_SMB_OFF_T */
                        }
                        pdata+=24;          /* ctime & st_blocks are not changed */
-                       tvs.actime = interpret_long_date(pdata); /* access_time */
-                       tvs.modtime = interpret_long_date(pdata+8); /* modification_time */
+                       tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata)); /* access_time */
+                       tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+8)); /* modification_time */
                        pdata+=16;
                        set_owner = (uid_t)IVAL(pdata,0);
                        pdata += 8;
index ba13897773db80078af9677787ea37307e4bd0f1..59d6fa01135f4ffb90b1437e8585159ed420e2d6 100644 (file)
@@ -2467,7 +2467,8 @@ static BOOL run_trans2test(int dummy)
        struct cli_state *cli;
        int fnum;
        SMB_OFF_T size;
-       time_t c_time, a_time, m_time, w_time, m_time2;
+       time_t c_time, a_time, m_time, m_time2;
+       struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
        const char *fname = "\\trans2.tst";
        const char *dname = "\\trans2";
        const char *fname2 = "\\trans2\\trans2.tst";
@@ -2483,8 +2484,8 @@ static BOOL run_trans2test(int dummy)
        cli_unlink(cli, fname);
        fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
-       if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
-                          NULL, NULL)) {
+       if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
+                          &m_time_ts, NULL)) {
                printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
@@ -2539,13 +2540,13 @@ static BOOL run_trans2test(int dummy)
        fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        cli_close(cli, fnum);
-       if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &w_time
-                           &m_time, &size, NULL, NULL)) {
+       if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time_ts, &size, NULL, NULL)) {
                printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {
-               if (w_time < 60*60*24*2) {
-                       printf("write time=%s", ctime(&w_time));
+               if (w_time_ts.tv_sec < 60*60*24*2) {
+                       printf("write time=%s", ctime(&w_time_ts.tv_sec));
                        printf("This system appears to set a initial 0 write time\n");
                        correct = False;
                }
@@ -2561,8 +2562,8 @@ static BOOL run_trans2test(int dummy)
                correct = False;
        }
        sleep(3);
-       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &w_time
-                           &m_time, &size, NULL, NULL)) {
+       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time_ts, &size, NULL, NULL)) {
                printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
@@ -2571,8 +2572,8 @@ static BOOL run_trans2test(int dummy)
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
        cli_close(cli, fnum);
-       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &w_time
-                           &m_time2, &size, NULL, NULL)) {
+       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time2_ts, &size, NULL, NULL)) {
                printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {