Annotation of embedaddon/curl/src/tool_filetime.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
! 9: *
! 10: * This software is licensed as described in the file COPYING, which
! 11: * you should have received as part of this distribution. The terms
! 12: * are also available at https://curl.haxx.se/docs/copyright.html.
! 13: *
! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
! 15: * copies of the Software, and permit persons to whom the Software is
! 16: * furnished to do so, under the terms of the COPYING file.
! 17: *
! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
! 19: * KIND, either express or implied.
! 20: *
! 21: ***************************************************************************/
! 22: #include "tool_filetime.h"
! 23:
! 24: #ifdef HAVE_UTIME_H
! 25: # include <utime.h>
! 26: #elif defined(HAVE_SYS_UTIME_H)
! 27: # include <sys/utime.h>
! 28: #endif
! 29:
! 30: curl_off_t getfiletime(const char *filename, FILE *error_stream)
! 31: {
! 32: curl_off_t result = -1;
! 33:
! 34: /* Windows stat() may attempt to adjust the unix GMT file time by a daylight
! 35: saving time offset and since it's GMT that is bad behavior. When we have
! 36: access to a 64-bit type we can bypass stat and get the times directly. */
! 37: #if defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)
! 38: HANDLE hfile;
! 39:
! 40: hfile = CreateFileA(filename, FILE_READ_ATTRIBUTES,
! 41: (FILE_SHARE_READ | FILE_SHARE_WRITE |
! 42: FILE_SHARE_DELETE),
! 43: NULL, OPEN_EXISTING, 0, NULL);
! 44: if(hfile != INVALID_HANDLE_VALUE) {
! 45: FILETIME ft;
! 46: if(GetFileTime(hfile, NULL, NULL, &ft)) {
! 47: curl_off_t converted = (curl_off_t)ft.dwLowDateTime
! 48: | ((curl_off_t)ft.dwHighDateTime) << 32;
! 49:
! 50: if(converted < CURL_OFF_T_C(116444736000000000)) {
! 51: fprintf(error_stream,
! 52: "Failed to get filetime: underflow\n");
! 53: }
! 54: else {
! 55: result = (converted - CURL_OFF_T_C(116444736000000000)) / 10000000;
! 56: }
! 57: }
! 58: else {
! 59: fprintf(error_stream,
! 60: "Failed to get filetime: "
! 61: "GetFileTime failed: GetLastError %u\n",
! 62: (unsigned int)GetLastError());
! 63: }
! 64: CloseHandle(hfile);
! 65: }
! 66: else if(GetLastError() != ERROR_FILE_NOT_FOUND) {
! 67: fprintf(error_stream,
! 68: "Failed to get filetime: "
! 69: "CreateFile failed: GetLastError %u\n",
! 70: (unsigned int)GetLastError());
! 71: }
! 72: #else
! 73: struct_stat statbuf;
! 74: if(-1 != stat(filename, &statbuf)) {
! 75: result = (curl_off_t)statbuf.st_mtime;
! 76: }
! 77: else if(errno != ENOENT) {
! 78: fprintf(error_stream,
! 79: "Failed to get filetime: %s\n", strerror(errno));
! 80: }
! 81: #endif
! 82: return result;
! 83: }
! 84:
! 85: #if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \
! 86: (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8))
! 87: void setfiletime(curl_off_t filetime, const char *filename,
! 88: FILE *error_stream)
! 89: {
! 90: if(filetime >= 0) {
! 91: /* Windows utime() may attempt to adjust the unix GMT file time by a daylight
! 92: saving time offset and since it's GMT that is bad behavior. When we have
! 93: access to a 64-bit type we can bypass utime and set the times directly. */
! 94: #if defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)
! 95: HANDLE hfile;
! 96:
! 97: /* 910670515199 is the maximum unix filetime that can be used as a
! 98: Windows FILETIME without overflow: 30827-12-31T23:59:59. */
! 99: if(filetime > CURL_OFF_T_C(910670515199)) {
! 100: fprintf(error_stream,
! 101: "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
! 102: " on outfile: overflow\n", filetime);
! 103: return;
! 104: }
! 105:
! 106: hfile = CreateFileA(filename, FILE_WRITE_ATTRIBUTES,
! 107: (FILE_SHARE_READ | FILE_SHARE_WRITE |
! 108: FILE_SHARE_DELETE),
! 109: NULL, OPEN_EXISTING, 0, NULL);
! 110: if(hfile != INVALID_HANDLE_VALUE) {
! 111: curl_off_t converted = ((curl_off_t)filetime * 10000000) +
! 112: CURL_OFF_T_C(116444736000000000);
! 113: FILETIME ft;
! 114: ft.dwLowDateTime = (DWORD)(converted & 0xFFFFFFFF);
! 115: ft.dwHighDateTime = (DWORD)(converted >> 32);
! 116: if(!SetFileTime(hfile, NULL, &ft, &ft)) {
! 117: fprintf(error_stream,
! 118: "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
! 119: " on outfile: SetFileTime failed: GetLastError %u\n",
! 120: filetime, (unsigned int)GetLastError());
! 121: }
! 122: CloseHandle(hfile);
! 123: }
! 124: else {
! 125: fprintf(error_stream,
! 126: "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
! 127: " on outfile: CreateFile failed: GetLastError %u\n",
! 128: filetime, (unsigned int)GetLastError());
! 129: }
! 130:
! 131: #elif defined(HAVE_UTIMES)
! 132: struct timeval times[2];
! 133: times[0].tv_sec = times[1].tv_sec = (time_t)filetime;
! 134: times[0].tv_usec = times[1].tv_usec = 0;
! 135: if(utimes(filename, times)) {
! 136: fprintf(error_stream,
! 137: "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
! 138: " on outfile: %s\n", filetime, strerror(errno));
! 139: }
! 140:
! 141: #elif defined(HAVE_UTIME)
! 142: struct utimbuf times;
! 143: times.actime = (time_t)filetime;
! 144: times.modtime = (time_t)filetime;
! 145: if(utime(filename, ×)) {
! 146: fprintf(error_stream,
! 147: "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
! 148: " on outfile: %s\n", filetime, strerror(errno));
! 149: }
! 150: #endif
! 151: }
! 152: }
! 153: #endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \
! 154: (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>