1 /* 2 * ntfstime.h - NTFS time related functions. Originated from the Linux-NTFS project. 3 * 4 * Copyright (c) 2005 Anton Altaparmakov 5 * Copyright (c) 2005 Yura Pakhuchiy 6 * Copyright (c) 2010 Jean-Pierre Andre 7 * 8 * This program/include file is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as published 10 * by the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program/include file is distributed in the hope that it will be 14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program (in the main directory of the NTFS-3G 20 * distribution in the file COPYING); if not, write to the Free Software 21 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #ifndef _NTFS_NTFSTIME_H 25 #define _NTFS_NTFSTIME_H 26 27 #ifdef HAVE_TIME_H 28 #include <time.h> 29 #endif 30 #ifdef HAVE_SYS_STAT_H 31 #include <sys/stat.h> 32 #endif 33 #ifdef HAVE_GETTIMEOFDAY 34 #include <sys/time.h> 35 #endif 36 37 #include "types.h" 38 39 /* 40 * assume "struct timespec" is not defined if st_mtime is not defined 41 */ 42 #if !defined(st_mtime) & !defined(__timespec_defined) 43 struct timespec { 44 time_t tv_sec; 45 long tv_nsec; 46 } ; 47 #endif 48 49 /* 50 * There are four times more conversions of internal representation 51 * to ntfs representation than any other conversion, so the most 52 * efficient internal representation is ntfs representation 53 * (with low endianness) 54 */ 55 typedef sle64 ntfs_time; 56 57 #define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000) 58 59 /** 60 * ntfs2timespec - Convert an NTFS time to Unix time 61 * @ntfs_time: An NTFS time in 100ns units since 1601 62 * 63 * NTFS stores times as the number of 100ns intervals since January 1st 1601 at 64 * 00:00 UTC. This system will not suffer from Y2K problems until ~57000AD. 65 * 66 * Return: A Unix time (number of seconds since 1970, and nanoseconds) 67 */ 68 static __inline__ struct timespec ntfs2timespec(ntfs_time ntfstime) 69 { 70 struct timespec spec; 71 s64 cputime; 72 73 cputime = sle64_to_cpu(ntfstime); 74 spec.tv_sec = (cputime - (NTFS_TIME_OFFSET)) / 10000000; 75 spec.tv_nsec = (cputime - (NTFS_TIME_OFFSET) 76 - (s64)spec.tv_sec*10000000)*100; 77 /* force zero nsec for overflowing dates */ 78 if ((spec.tv_nsec < 0) || (spec.tv_nsec > 999999999)) 79 spec.tv_nsec = 0; 80 return (spec); 81 } 82 83 /** 84 * timespec2ntfs - Convert Linux time to NTFS time 85 * @utc_time: Linux time to convert to NTFS 86 * 87 * Convert the Linux time @utc_time to its corresponding NTFS time. 88 * 89 * Linux stores time in a long at present and measures it as the number of 90 * 1-second intervals since 1st January 1970, 00:00:00 UTC 91 * with a separated non-negative nanosecond value 92 * 93 * NTFS uses Microsoft's standard time format which is stored in a sle64 and is 94 * measured as the number of 100 nano-second intervals since 1st January 1601, 95 * 00:00:00 UTC. 96 * 97 * Return: An NTFS time (100ns units since Jan 1601) 98 */ 99 static __inline__ ntfs_time timespec2ntfs(struct timespec spec) 100 { 101 s64 units; 102 103 units = (s64)spec.tv_sec * 10000000 104 + NTFS_TIME_OFFSET + spec.tv_nsec/100; 105 return (cpu_to_le64(units)); 106 } 107 108 /* 109 * Return the current time in ntfs format 110 */ 111 112 static __inline__ ntfs_time ntfs_current_time(void) 113 { 114 struct timespec now; 115 116 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_SYS_CLOCK_GETTIME) 117 clock_gettime(CLOCK_REALTIME, &now); 118 #elif defined(HAVE_GETTIMEOFDAY) 119 struct timeval microseconds; 120 121 gettimeofday(µseconds, (struct timezone*)NULL); 122 now.tv_sec = microseconds.tv_sec; 123 now.tv_nsec = microseconds.tv_usec*1000; 124 #else 125 now.tv_sec = time((time_t*)NULL); 126 now.tv_nsec = 0; 127 #endif 128 return (timespec2ntfs(now)); 129 } 130 131 #endif /* _NTFS_NTFSTIME_H */ 132