^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) This file is part of the GNU C Library.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Contributed by Paul Eggert (eggert@twinsun.com).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) The GNU C Library is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) modify it under the terms of the GNU Library General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) published by the Free Software Foundation; either version 2 of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) License, or (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) The GNU C Library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) Library General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) You should have received a copy of the GNU Library General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) License along with the GNU C Library; see the file COPYING.LIB. If not,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) Boston, MA 02111-1307, USA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * dgb 10/02/98: ripped this from glibc source to help convert timestamps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * to unix time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 10/04/98: added new table-based lookup after seeing how ugly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * the gnu code is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * blf 09/27/99: ripped out all the old code and inserted new table from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * John Brockmeyer (without leap second corrections)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * rewrote udf_stamp_to_time and fixed timezone accounting in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * udf_time_to_stamp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * We don't take into account leap seconds. This may be correct or incorrect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * For more NIST information (especially dealing with leap seconds), see:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "udfdecl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) udf_disk_stamp_to_time(struct timespec64 *dest, struct timestamp src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u16 year = le16_to_cpu(src.year);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) uint8_t type = typeAndTimezone >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int16_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (type == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) offset = typeAndTimezone << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* sign extent offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) offset = (offset >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (offset == -2047) /* unspecified offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) dest->tv_sec = mktime64(year, src.month, src.day, src.hour, src.minute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) src.second);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dest->tv_sec -= offset * 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) src.hundredsOfMicroseconds * 100 + src.microseconds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Sanitize nanosecond field since reportedly some filesystems are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * recorded with bogus sub-second values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) dest->tv_nsec %= NSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) udf_time_to_disk_stamp(struct timestamp *dest, struct timespec64 ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) time64_t seconds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int16_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct tm tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) offset = -sys_tz.tz_minuteswest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) seconds = ts.tv_sec + offset * 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) time64_to_tm(seconds, 0, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) dest->year = cpu_to_le16(tm.tm_year + 1900);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) dest->month = tm.tm_mon + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) dest->day = tm.tm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) dest->hour = tm.tm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dest->minute = tm.tm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dest->second = tm.tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) dest->centiseconds = ts.tv_nsec / 10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) dest->centiseconds * 10000) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) dest->hundredsOfMicroseconds * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* EOF */