summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/client/client.c4
-rw-r--r--source3/client/clitar.c37
-rw-r--r--source3/include/client.h6
-rw-r--r--source3/lib/time.c173
-rw-r--r--source3/lib/util.c2
-rw-r--r--source3/libsmb/cliconnect.c4
-rw-r--r--source3/libsmb/clifile.c7
-rw-r--r--source3/libsmb/clifsinfo.c4
-rw-r--r--source3/libsmb/clilist.c24
-rw-r--r--source3/libsmb/clirap.c14
-rw-r--r--source3/libsmb/libsmbclient.c84
-rw-r--r--source3/smbd/nttrans.c71
-rw-r--r--source3/smbd/trans2.c164
-rw-r--r--source3/torture/torture.c23
14 files changed, 378 insertions, 239 deletions
diff --git a/source3/client/client.c b/source3/client/client.c
index 1ff63aa836..385eb5a7cf 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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),
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index f0d0ac595c..87ca3245c1 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -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 */
diff --git a/source3/include/client.h b/source3/include/client.h
index d11d198e1a..a89e39d160 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -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 */
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 0bfdfac856..fa4ef398f2 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -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,64 +286,79 @@ 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
This is an absolute version of the one above.
@@ -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
diff --git a/source3/lib/util.c b/source3/lib/util.c
index ef954015d6..20ff4514a0 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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;
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 3e4b6f0545..0e179416dc 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -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) {
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 9beafc55fb..fb07dae427 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -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));
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index c6aa6a70a0..9c3b6e3aed 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -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);
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index b022a107d0..18c058f9df 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -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, ".")) {
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index 1227b26b2f..677c8f1fc3 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -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 );
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index abeb66b373..2656bd0f04 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -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) {
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index d107bf84d3..4dcc807c30 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index b4799d83cc..87bfa18dcf 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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;
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index ba13897773..59d6fa0113 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -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 {