svn commit: samba r7168 - in branches/SAMBA_3_0: examples/libsmbclient/smbwrapper source/libsmb

derrell at samba.org derrell at samba.org
Wed Jun 1 17:40:41 GMT 2005


Author: derrell
Date: 2005-06-01 17:40:40 +0000 (Wed, 01 Jun 2005)
New Revision: 7168

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=7168

Log:
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.


Modified:
   branches/SAMBA_3_0/examples/libsmbclient/smbwrapper/smbw_stat.c
   branches/SAMBA_3_0/source/libsmb/libsmb_compat.c
   branches/SAMBA_3_0/source/libsmb/libsmbclient.c


Changeset:
Modified: branches/SAMBA_3_0/examples/libsmbclient/smbwrapper/smbw_stat.c
===================================================================
--- branches/SAMBA_3_0/examples/libsmbclient/smbwrapper/smbw_stat.c	2005-06-01 16:23:54 UTC (rev 7167)
+++ branches/SAMBA_3_0/examples/libsmbclient/smbwrapper/smbw_stat.c	2005-06-01 17:40:40 UTC (rev 7168)
@@ -22,53 +22,8 @@
 
 #include "smbw.h"
 
-static int timezone_diff = -1;
-
-#define TM_YEAR_BASE 1900
-
-/*******************************************************************
-yield the difference between *A and *B, in seconds, ignoring leap seconds
-********************************************************************/
-static int tm_diff(struct tm *a, struct tm *b)
-{
-  int ay = a->tm_year + (TM_YEAR_BASE - 1);
-  int by = b->tm_year + (TM_YEAR_BASE - 1);
-  int intervening_leap_days =
-    (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
-  int years = ay - by;
-  int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
-  int hours = 24*days + (a->tm_hour - b->tm_hour);
-  int minutes = 60*hours + (a->tm_min - b->tm_min);
-  int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
-
-  return seconds;
-}
-
-/*******************************************************************
-  return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
-  ******************************************************************/
-static int TimeZone(time_t t)
-{
-  struct tm *tm = gmtime(&t);
-  struct tm tm_utc;
-  if (!tm)
-    return 0;
-  tm_utc = *tm;
-  tm = localtime(&t);
-  if (!tm)
-    return 0;
-  return tm_diff(&tm_utc,tm);
-
-}
-
-
 static void copy_stat(struct SMBW_stat *external, struct stat *internal)
 {
-        if (timezone_diff < 0)
-        {
-            timezone_diff = TimeZone(time(NULL));
-        }
-
         external->s_dev = internal->st_dev;
         external->s_ino = internal->st_ino;
         external->s_mode = internal->st_mode;
@@ -79,9 +34,9 @@
         external->s_size = internal->st_size;
         external->s_blksize = internal->st_blksize;
         external->s_blocks = internal->st_blocks;
-        external->s_atime = internal->st_atime + timezone_diff;
-        external->s_mtime = internal->st_mtime + timezone_diff;
-        external->s_ctime = internal->st_ctime + timezone_diff;
+        external->s_atime = internal->st_atime;
+        external->s_mtime = internal->st_mtime;
+        external->s_ctime = internal->st_ctime;
 }
 
 

Modified: branches/SAMBA_3_0/source/libsmb/libsmb_compat.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/libsmb_compat.c	2005-06-01 16:23:54 UTC (rev 7167)
+++ branches/SAMBA_3_0/source/libsmb/libsmb_compat.c	2005-06-01 17:40:40 UTC (rev 7168)
@@ -303,14 +303,16 @@
 #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
 

Modified: branches/SAMBA_3_0/source/libsmb/libsmbclient.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/libsmbclient.c	2005-06-01 16:23:54 UTC (rev 7167)
+++ branches/SAMBA_3_0/source/libsmb/libsmbclient.c	2005-06-01 17:40:40 UTC (rev 7168)
@@ -1245,7 +1245,10 @@
         }
 
 	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 @@
 
 	}
 
-	/*  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_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,8 +2875,23 @@
 
 	}
   
-	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),
                             share, sizeof(share),
@@ -2908,22 +2913,46 @@
 		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;
 }
 
 



More information about the samba-cvs mailing list