diff options
author | Jeremy Allison <jra@samba.org> | 2006-08-24 16:44:00 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:38:48 -0500 |
commit | a64925ddff467a47f7adfac4b1b977ddc0c7f4ef (patch) | |
tree | 0c228a2046097065d34dc62a744747509689e09c | |
parent | 26f55cb40de4556774ac3a4ef0e46003d85477a4 (diff) | |
download | samba-a64925ddff467a47f7adfac4b1b977ddc0c7f4ef.tar.gz samba-a64925ddff467a47f7adfac4b1b977ddc0c7f4ef.tar.bz2 samba-a64925ddff467a47f7adfac4b1b977ddc0c7f4ef.zip |
r17800: Start using struct timespec internally for file times
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)
-rw-r--r-- | source3/client/client.c | 4 | ||||
-rw-r--r-- | source3/client/clitar.c | 37 | ||||
-rw-r--r-- | source3/include/client.h | 6 | ||||
-rw-r--r-- | source3/lib/time.c | 173 | ||||
-rw-r--r-- | source3/lib/util.c | 2 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 4 | ||||
-rw-r--r-- | source3/libsmb/clifile.c | 7 | ||||
-rw-r--r-- | source3/libsmb/clifsinfo.c | 4 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 24 | ||||
-rw-r--r-- | source3/libsmb/clirap.c | 14 | ||||
-rw-r--r-- | source3/libsmb/libsmbclient.c | 84 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 71 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 164 | ||||
-rw-r--r-- | source3/torture/torture.c | 23 |
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 { |