gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 22/173: tool_operate: Fix --remote-time incorrect t


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 22/173: tool_operate: Fix --remote-time incorrect times on Windows
Date: Fri, 24 Feb 2017 14:00:44 +0100

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to annotated tag gnurl-7.53.1
in repository gnurl.

commit ee3c83f39c90126cabb9be896931725c32f22e09
Author: Jay Satiro <address@hidden>
AuthorDate: Fri Nov 11 02:48:52 2016 -0500

    tool_operate: Fix --remote-time incorrect times on Windows
    
    - Use Windows API SetFileTime to set the file time instead of utime.
    
    Avoid utime on Windows if possible because it may apply a daylight
    saving time offset to our UTC file time.
    
    Bug: https://curl.haxx.se/mail/archive-2016-11/0033.html
    Reported-by: Tim
    
    Closes https://github.com/curl/curl/pull/1121
---
 docs/FAQ           | 10 ++++++----
 src/tool_operate.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/docs/FAQ b/docs/FAQ
index d663811a2..9157022a2 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -1016,10 +1016,12 @@ FAQ
 
   4.13 Why is curl -R on Windows one hour off?
 
-  During daylight savings time, when -R is used, curl will set a time that
-  appears one hour off. This happens due to a flaw in how Windows stores and
-  uses file modification times and it is not easily worked around. For details
-  on this problem, read this: http://www.codeproject.com/datetime/dstbugs.asp
+  Since curl 7.53.0 this issue should be fixed as long as curl was built with
+  any modern compiler that allows for a 64-bit curl_off_t type. For older
+  compilers or prior curl versions it may set a time that appears one hour off.
+  This happens due to a flaw in how Windows stores and uses file modification
+  times and it is not easily worked around. For more details read this:
+  http://www.codeproject.com/datetime/dstbugs.asp
 
   4.14 Redirects work in browser but not with curl!
 
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 26662aec5..4fa32bcf3 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1727,20 +1727,65 @@ static CURLcode operate_do(struct GlobalConfig *global,
         }
 #endif
 
-#ifdef HAVE_UTIME
+#if defined(HAVE_UTIME) || \
+    (defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8))
         /* File time can only be set _after_ the file has been closed */
         if(!result && config->remote_time && outs.s_isreg && outs.filename) {
           /* Ask libcurl if we got a remote file time */
           long filetime = -1;
           curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
           if(filetime >= 0) {
+/* Windows utime() may attempt to adjust our unix gmt 'filetime' by a daylight
+   saving time offset and since it's GMT that is bad behavior. When we have
+   access to a 64-bit type we can bypass utime and set the times directly. */
+#if defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8)
+            /* 910670515199 is the maximum unix filetime that can be used as a
+               Windows FILETIME without overflow: 30827-12-31T23:59:59. */
+            if(filetime <= CURL_OFF_T_C(910670515199)) {
+              HANDLE hfile = CreateFileA(outs.filename, FILE_WRITE_ATTRIBUTES,
+                                         (FILE_SHARE_READ | FILE_SHARE_WRITE |
+                                          FILE_SHARE_DELETE),
+                                         NULL, OPEN_EXISTING, 0, NULL);
+              if(hfile != INVALID_HANDLE_VALUE) {
+                curl_off_t converted = ((curl_off_t)filetime * 10000000) +
+                                       CURL_OFF_T_C(116444736000000000);
+                FILETIME ft;
+                ft.dwLowDateTime = (DWORD)(converted & 0xFFFFFFFF);
+                ft.dwHighDateTime = (DWORD)(converted >> 32);
+                if(!SetFileTime(hfile, NULL, &ft, &ft)) {
+                  fprintf(config->global->errors,
+                          "Failed to set filetime %ld on outfile: "
+                          "SetFileTime failed: GetLastError %u\n",
+                          filetime, GetLastError());
+                }
+                CloseHandle(hfile);
+              }
+              else {
+                fprintf(config->global->errors,
+                        "Failed to set filetime %ld on outfile: "
+                        "CreateFile failed: GetLastError %u\n",
+                        filetime, GetLastError());
+              }
+            }
+            else {
+              fprintf(config->global->errors,
+                      "Failed to set filetime %ld on outfile: overflow\n",
+                      filetime);
+            }
+#elif defined(HAVE_UTIME)
             struct utimbuf times;
             times.actime = (time_t)filetime;
             times.modtime = (time_t)filetime;
-            utime(outs.filename, &times); /* set the time we got */
+            if(utime(outs.filename, &times)) {
+              fprintf(config->global->errors,
+                      "Failed to set filetime %ld on outfile: errno %d\n",
+                      filetime, errno);
+            }
+#endif
           }
         }
-#endif
+#endif /* defined(HAVE_UTIME) || \
+          (defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8)) */
 
 #ifdef USE_METALINK
         if(!metalink && config->use_metalink && result == CURLE_OK) {

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]