diff options
-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 1ff63aa8363..385eb5a7cf5 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 f0d0ac595c2..87ca3245c11 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 d11d198e1a5..a89e39d1605 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 0bfdfac856b..fa4ef398f2c 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 ef954015d66..20ff4514a02 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 3e4b6f05453..0e179416dc7 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 9beafc55fb0..fb07dae427d 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 c6aa6a70a03..9c3b6e3aed3 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 b022a107d09..18c058f9dfb 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 1227b26b2ff..677c8f1fc3d 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 abeb66b3733..2656bd0f046 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 d107bf84d36..4dcc807c30c 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 b4799d83cce..87bfa18dcfe 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 ba13897773d..59d6fa01135 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 { |