diff options
author | Derrell Lipman <derrell@samba.org> | 2005-06-01 17:40:40 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:57:04 -0500 |
commit | e317034997bbeab447298070afdb1b78c60e0e69 (patch) | |
tree | 06e4d09719d735ebba861a74e2e60fe9f404623e /source3/libsmb | |
parent | 0100bb0eb697105db7ef1473455a8b180ca43cb4 (diff) | |
download | samba-e317034997bbeab447298070afdb1b78c60e0e69.tar.gz samba-e317034997bbeab447298070afdb1b78c60e0e69.tar.bz2 samba-e317034997bbeab447298070afdb1b78c60e0e69.zip |
r7168: Updating file times from libsmbclient was not working for win98. Although
the function that was being used to set attributes is a core protocol
function (SMBsetatr = 0x09), it does not appear to work on win98. As a
temporary measure, when file times are to be set, this version opens the
file and uses SMBsetattrE = 0x22 instead. (The other advantage of this
function over the original one is that it supports setting access time as
well as modification time.)
The next step, the proper solution if it can be made to work, is to write
functions that use TRANS2_SET_PATH_INFO instead.
(This used to be commit bab0bf7f4f9d2a4b6fcee4429094349302bbeb33)
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/libsmb_compat.c | 10 | ||||
-rw-r--r-- | source3/libsmb/libsmbclient.c | 95 |
2 files changed, 68 insertions, 37 deletions
diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 83088a14de..3dc60f7240 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -303,14 +303,16 @@ int smbc_utimes(const char *fname, struct timeval *tbuf) #ifdef HAVE_UTIME_H int smbc_utime(const char *fname, struct utimbuf *utbuf) { - struct timeval tv; + struct timeval tv[2]; if (utbuf == NULL) return statcont->utimes(statcont, fname, NULL); - tv.tv_sec = utbuf->modtime; - tv.tv_usec = 0; - return statcont->utimes(statcont, fname, &tv); + tv[0].tv_sec = utbuf->actime; + tv[1].tv_sec = utbuf->modtime; + tv[0].tv_usec = tv[1].tv_usec = 0; + + return statcont->utimes(statcont, fname, tv); } #endif diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ee7516630b..296dbc7f5b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1245,7 +1245,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, } if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; + if (m_time != NULL) { + if (a_time != NULL) *a_time = *m_time; + if (c_time != NULL) *c_time = *m_time; + } srv->no_pathinfo2 = True; return True; } @@ -1303,22 +1306,6 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) } - /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - - int job = smbc_stat_printjob(srv, path, NULL, NULL); - if (job == -1) { - - return -1; - - } - if ((err = cli_printjob_del(&srv->cli, job)) != 0) { - - - return -1; - - } - } else */ - if (!cli_unlink(&srv->cli, path)) { errno = smbc_errno(context, &srv->cli); @@ -2864,11 +2851,14 @@ int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) { + int fd; + int ret; SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - uint16 mode; - time_t t = (tbuf == NULL ? time(NULL) : tbuf->tv_sec); + time_t c_time; + time_t a_time; + time_t m_time; if (!context || !context->internal || !context->internal->_initialized) { @@ -2885,7 +2875,22 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) } - DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t))); + if (tbuf == NULL) { + a_time = m_time = time(NULL); + } else { + a_time = tbuf[0].tv_sec; + m_time = tbuf[1].tv_sec; + } + + { + char atimebuf[32]; + char mtimebuf[32]; + + DEBUG(4, ("smbc_utimes(%s, atime = %s mtime = %s)\n", + fname, + ctime_r(&a_time, atimebuf), + ctime_r(&m_time, mtimebuf))); + } if (smbc_parse_path(context, fname, server, sizeof(server), @@ -2908,22 +2913,46 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) return -1; /* errno set by smbc_server */ } - if (!smbc_getatr(context, srv, path, - &mode, NULL, - NULL, NULL, NULL, - NULL)) { + /* + * cli_setatr() does not work on win98, and it also doesn't support + * setting the access time (only the modification time), so in all + * cases, we open the specified file and use cli_setattrE() which + * should work on all OS versions, and supports both times. + */ + if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + + errno = smbc_errno(context, &srv->cli); return -1; - } + + } - if (!cli_setatr(&srv->cli, path, mode, t)) { - /* some servers always refuse directory changes */ - if (!(mode & aDIR)) { - errno = smbc_errno(context, &srv->cli); - return -1; - } - } + /* Get the creat time of the file; we'll need it in the set call */ + ret = cli_getattrE(&srv->cli, fd, NULL, NULL, &c_time, NULL, NULL); - return 0; + /* Some OS versions don't support create time */ + if (c_time == 0) { + c_time = time(NULL); + } + + /* + * For sanity sake, since there is no POSIX function to set the create + * time of a file, if the existing create time is greater than either + * of access time or modification time, set create time to the + * smallest of those. This ensure that the create time of a file is + * never greater than its last access or modification time. + */ + if (c_time > a_time) c_time = a_time; + if (c_time > m_time) c_time = m_time; + + /* If we sucessfully retrieved the create time... */ + if (ret) { + /* ... then set the new attributes */ + ret = cli_setattrE(&srv->cli, fd, c_time, a_time, m_time); + } + + cli_close(&srv->cli, fd); + + return ret; } |