gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnurl] 47/150: time-cond: fix reading the file modificatio


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 47/150: time-cond: fix reading the file modification time on Windows
Date: Fri, 30 Mar 2018 16:48:21 +0200

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

ng0 pushed a commit to branch master
in repository gnurl.

commit d25b0503795f1fbf557632ce870298f52f2a78c1
Author: Michael Kaufmann <address@hidden>
AuthorDate: Mon Feb 5 21:57:39 2018 +0100

    time-cond: fix reading the file modification time on Windows
    
    On Windows, stat() may adjust the unix file time by a daylight saving time
    offset. Avoid this by calling GetFileTime() instead.
    
    Fixes #2164
    Closes #2204
---
 src/Makefile.inc    |   2 +
 src/tool_cfgable.h  |   2 +-
 src/tool_filetime.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/tool_filetime.h |  38 +++++++++++++
 src/tool_getparam.c |  17 +++---
 src/tool_operate.c  |  95 ++------------------------------
 6 files changed, 210 insertions(+), 98 deletions(-)

diff --git a/src/Makefile.inc b/src/Makefile.inc
index d3c7c2bbf..e0506c7f5 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -37,6 +37,7 @@ CURL_CFILES = \
        tool_dirhie.c \
        tool_doswin.c \
        tool_easysrc.c \
+       tool_filetime.c \
        tool_formparse.c \
        tool_getparam.c \
        tool_getpass.c \
@@ -77,6 +78,7 @@ CURL_HFILES = \
        tool_dirhie.h \
        tool_doswin.h \
        tool_easysrc.h \
+       tool_filetime.h \
        tool_formparse.h \
        tool_getparam.h \
        tool_getpass.h \
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 713739e7a..0f316775d 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -169,7 +169,7 @@ struct OperationConfig {
   long proxy_ssl_version;
   long ip_version;
   curl_TimeCond timecond;
-  time_t condtime;
+  curl_off_t condtime;
   struct curl_slist *headers;
   struct curl_slist *proxyheaders;
   curl_mime *mimepost;
diff --git a/src/tool_filetime.c b/src/tool_filetime.c
new file mode 100644
index 000000000..6071e44d2
--- /dev/null
+++ b/src/tool_filetime.c
@@ -0,0 +1,154 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_filetime.h"
+
+#ifdef HAVE_UTIME_H
+#  include <utime.h>
+#elif defined(HAVE_SYS_UTIME_H)
+#  include <sys/utime.h>
+#endif
+
+curl_off_t getfiletime(const char *filename, FILE *error_stream)
+{
+  curl_off_t result = -1;
+
+/* Windows stat() may attempt to adjust the unix GMT file time 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 stat and get the times directly. */
+#if defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)
+  HANDLE hfile;
+
+  hfile = CreateFileA(filename, FILE_READ_ATTRIBUTES,
+                      (FILE_SHARE_READ | FILE_SHARE_WRITE |
+                       FILE_SHARE_DELETE),
+                      NULL, OPEN_EXISTING, 0, NULL);
+  if(hfile != INVALID_HANDLE_VALUE) {
+    FILETIME ft;
+    if(GetFileTime(hfile, NULL, NULL, &ft)) {
+      curl_off_t converted = (curl_off_t)ft.dwLowDateTime
+          | ((curl_off_t)ft.dwHighDateTime) << 32;
+
+      if(converted < CURL_OFF_T_C(116444736000000000)) {
+        fprintf(error_stream,
+                "Failed to get filetime: underflow\n");
+      }
+      else {
+        result = (converted - CURL_OFF_T_C(116444736000000000)) / 10000000;
+      }
+    }
+    else {
+      fprintf(error_stream,
+              "Failed to get filetime: "
+              "GetFileTime failed: GetLastError %u\n",
+              (unsigned int)GetLastError());
+    }
+    CloseHandle(hfile);
+  }
+  else if(GetLastError() != ERROR_FILE_NOT_FOUND) {
+    fprintf(error_stream,
+            "Failed to get filetime: "
+            "CreateFile failed: GetLastError %u\n",
+            (unsigned int)GetLastError());
+  }
+#else
+  struct_stat statbuf;
+  if(-1 != stat(filename, &statbuf)) {
+    result = (curl_off_t)statbuf.st_mtime;
+  }
+  else if(errno != ENOENT) {
+    fprintf(error_stream,
+            "Failed to get filetime: %s\n", strerror(errno));
+  }
+#endif
+  return result;
+}
+
+#if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \
+    (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8))
+void setfiletime(curl_off_t filetime, const char *filename,
+    FILE *error_stream)
+{
+  if(filetime >= 0) {
+/* Windows utime() may attempt to adjust the unix GMT file time 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) && (SIZEOF_CURL_OFF_T >= 8)
+    HANDLE hfile;
+
+    /* 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)) {
+      fprintf(error_stream,
+              "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
+              " on outfile: overflow\n", filetime);
+      return;
+    }
+
+    hfile = CreateFileA(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(error_stream,
+                "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
+                " on outfile: SetFileTime failed: GetLastError %u\n",
+                filetime, (unsigned int)GetLastError());
+      }
+      CloseHandle(hfile);
+    }
+    else {
+      fprintf(error_stream,
+              "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
+              " on outfile: CreateFile failed: GetLastError %u\n",
+              filetime, (unsigned int)GetLastError());
+    }
+
+#elif defined(HAVE_UTIMES)
+    struct timeval times[2];
+    times[0].tv_sec = times[1].tv_sec = (time_t)filetime;
+    times[0].tv_usec = times[1].tv_usec = 0;
+    if(utimes(filename, times)) {
+      fprintf(error_stream,
+              "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
+              " on outfile: %s\n", filetime, strerror(errno));
+    }
+
+#elif defined(HAVE_UTIME)
+    struct utimbuf times;
+    times.actime = (time_t)filetime;
+    times.modtime = (time_t)filetime;
+    if(utime(filename, &times)) {
+      fprintf(error_stream,
+              "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
+              " on outfile: %s\n", filetime, strerror(errno));
+    }
+#endif
+  }
+}
+#endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \
+          (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */
diff --git a/src/tool_filetime.h b/src/tool_filetime.h
new file mode 100644
index 000000000..966a70b46
--- /dev/null
+++ b/src/tool_filetime.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_TOOL_FILETIME_H
+#define HEADER_CURL_TOOL_FILETIME_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+curl_off_t getfiletime(const char *filename, FILE *error_stream);
+
+#if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \
+    (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8))
+void setfiletime(curl_off_t filetime, const char *filename,
+    FILE *error_stream);
+#else
+#define setfiletime(a,b,c) Curl_nop_stmt
+#endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \
+          (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */
+
+#endif /* HEADER_CURL_TOOL_FILETIME_H */
+
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 015d63551..46e7dd3cd 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -31,6 +31,7 @@
 #include "tool_cfgable.h"
 #include "tool_cb_prg.h"
 #include "tool_convert.h"
+#include "tool_filetime.h"
 #include "tool_formparse.h"
 #include "tool_getparam.h"
 #include "tool_helpers.h"
@@ -2087,11 +2088,15 @@ ParameterError getparameter(const char *flag, /* f or 
-long-flag */
         break;
       }
       now = time(NULL);
-      config->condtime = curl_getdate(nextarg, &now);
-      if(-1 == (int)config->condtime) {
+      config->condtime = (curl_off_t)curl_getdate(nextarg, &now);
+      if(-1 == config->condtime) {
         /* now let's see if it is a file name to get the time from instead! */
-        struct_stat statbuf;
-        if(-1 == stat(nextarg, &statbuf)) {
+        curl_off_t filetime = getfiletime(nextarg, config->global->errors);
+        if(filetime >= 0) {
+          /* pull the time out from the file */
+          config->condtime = filetime;
+        }
+        else {
           /* failed, remove time condition */
           config->timecond = CURL_TIMECOND_NONE;
           warnf(global,
@@ -2099,10 +2104,6 @@ ParameterError getparameter(const char *flag, /* f or 
-long-flag */
                 "a file name). Disabling time condition. "
                 "See curl_getdate(3) for valid date syntax.\n");
         }
-        else {
-          /* pull the time out from the file */
-          config->condtime = statbuf.st_mtime;
-        }
       }
       break;
     default: /* unknown flag */
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 5401955af..f326a0d0c 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -25,12 +25,6 @@
 #  include <fcntl.h>
 #endif
 
-#ifdef HAVE_UTIME_H
-#  include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-#  include <sys/utime.h>
-#endif
-
 #ifdef HAVE_LOCALE_H
 #  include <locale.h>
 #endif
@@ -56,6 +50,7 @@
 #include "tool_dirhie.h"
 #include "tool_doswin.h"
 #include "tool_easysrc.h"
+#include "tool_filetime.h"
 #include "tool_getparam.h"
 #include "tool_helpers.h"
 #include "tool_homedir.h"
@@ -174,79 +169,6 @@ static curl_off_t VmsSpecialSize(const char *name,
 }
 #endif /* __VMS */
 
-#if defined(HAVE_UTIME) || \
-    (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8))
-static void setfiletime(long filetime, const char *filename,
-                        FILE *error_stream)
-{
-  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) && (SIZEOF_CURL_OFF_T >= 8)
-    HANDLE hfile;
-
-#if (SIZEOF_LONG >= 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)) {
-      fprintf(error_stream,
-              "Failed to set filetime %ld on outfile: overflow\n",
-              filetime);
-      return;
-    }
-#endif /* SIZEOF_LONG >= 8 */
-
-    hfile = CreateFileA(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(error_stream,
-                "Failed to set filetime %ld on outfile: "
-                "SetFileTime failed: GetLastError %u\n",
-                filetime, GetLastError());
-      }
-      CloseHandle(hfile);
-    }
-    else {
-      fprintf(error_stream,
-              "Failed to set filetime %ld on outfile: "
-              "CreateFile failed: GetLastError %u\n",
-              filetime, GetLastError());
-    }
-
-#elif defined(HAVE_UTIMES)
-    struct timeval times[2];
-    times[0].tv_sec = times[1].tv_sec = filetime;
-    times[0].tv_usec = times[1].tv_usec = 0;
-    if(utimes(filename, times)) {
-      fprintf(error_stream,
-              "Failed to set filetime %ld on outfile: errno %d\n",
-              filetime, errno);
-    }
-
-#elif defined(HAVE_UTIME)
-    struct utimbuf times;
-    times.actime = (time_t)filetime;
-    times.modtime = (time_t)filetime;
-    if(utime(filename, &times)) {
-      fprintf(error_stream,
-              "Failed to set filetime %ld on outfile: errno %d\n",
-              filetime, errno);
-    }
-#endif
-  }
-}
-#endif /* defined(HAVE_UTIME) || \
-          (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */
-
 #define BUFFER_SIZE (100*1024)
 
 static CURLcode operate_do(struct GlobalConfig *global,
@@ -710,7 +632,7 @@ static CURLcode operate_do(struct GlobalConfig *global,
            * to be considered with one appended if implied CC
            */
 #ifdef __VMS
-          /* Calculate the real upload site for VMS */
+          /* Calculate the real upload size for VMS */
           infd = -1;
           if(stat(uploadfile, &fileinfo) == 0) {
             fileinfo.st_size = VmsSpecialSize(uploadfile, &fileinfo);
@@ -1232,7 +1154,7 @@ static CURLcode operate_do(struct GlobalConfig *global,
 #endif
 
         my_setopt_enum(curl, CURLOPT_TIMECONDITION, (long)config->timecond);
-        my_setopt(curl, CURLOPT_TIMEVALUE, (long)config->condtime);
+        my_setopt(curl, CURLOPT_TIMEVALUE_LARGE, config->condtime);
         my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
         customrequest_helper(config, config->httpreq, config->customrequest);
         my_setopt(curl, CURLOPT_STDERR, global->errors);
@@ -1841,18 +1763,13 @@ static CURLcode operate_do(struct GlobalConfig *global,
         }
 #endif
 
-#if defined(HAVE_UTIME) || \
-    (defined(WIN32) && (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)
-            setfiletime(filetime, outs.filename, config->global->errors);
+          curl_off_t filetime = -1;
+          curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime);
+          setfiletime(filetime, outs.filename, config->global->errors);
         }
-#endif /* defined(HAVE_UTIME) || \
-          (defined(WIN32) && (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]