1
0
mirror of https://github.com/moparisthebest/curl synced 2025-02-28 09:21:50 -05:00

tool_operate: move filetime code to its own function

Ref: https://github.com/curl/curl/pull/1378
This commit is contained in:
Marcel Raad 2017-04-01 11:22:53 +02:00
parent 81284374bf
commit 446eaa941d
No known key found for this signature in database
GPG Key ID: B7F13D981BBF1607

View File

@ -184,6 +184,64 @@ static curl_off_t VmsSpecialSize(const char *name,
}
#endif /* __VMS */
#if defined(HAVE_UTIME) || \
(defined(WIN32) && (CURL_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) && (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(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());
}
}
else {
fprintf(error_stream,
"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;
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) && (CURL_SIZEOF_CURL_OFF_T >= 8)) */
static CURLcode operate_do(struct GlobalConfig *global,
struct OperationConfig *config)
{
@ -1761,55 +1819,8 @@ static CURLcode operate_do(struct GlobalConfig *global,
/* 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;
if(utime(outs.filename, &times)) {
fprintf(config->global->errors,
"Failed to set filetime %ld on outfile: errno %d\n",
filetime, errno);
}
#endif
}
if(filetime >= 0)
setfiletime(filetime, outs.filename, config->global->errors);
}
#endif /* defined(HAVE_UTIME) || \
(defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8)) */