brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 78ecc63 Raw
90 lines · c
1// SPDX-License-Identifier: LGPL-2.0+2/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.3   This file is part of the GNU C Library.4   Contributed by Paul Eggert (eggert@twinsun.com). */5 6/*7 * dgb 10/02/98: ripped this from glibc source to help convert timestamps8 *               to unix time9 *     10/04/98: added new table-based lookup after seeing how ugly10 *               the gnu code is11 * blf 09/27/99: ripped out all the old code and inserted new table from12 *		 John Brockmeyer (without leap second corrections)13 *		 rewrote udf_stamp_to_time and fixed timezone accounting in14 *		 udf_time_to_stamp.15 */16 17/*18 * We don't take into account leap seconds. This may be correct or incorrect.19 * For more NIST information (especially dealing with leap seconds), see:20 * http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm21 */22 23#include "udfdecl.h"24 25#include <linux/types.h>26#include <linux/kernel.h>27#include <linux/time.h>28 29void30udf_disk_stamp_to_time(struct timespec64 *dest, struct timestamp src)31{32	u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);33	u16 year = le16_to_cpu(src.year);34	uint8_t type = typeAndTimezone >> 12;35	int16_t offset;36 37	if (type == 1) {38		offset = typeAndTimezone << 4;39		/* sign extent offset */40		offset = (offset >> 4);41		if (offset == -2047) /* unspecified offset */42			offset = 0;43	} else44		offset = 0;45 46	dest->tv_sec = mktime64(year, src.month, src.day, src.hour, src.minute,47			src.second);48	dest->tv_sec -= offset * 60;49 50	/*51	 * Sanitize nanosecond field since reportedly some filesystems are52	 * recorded with bogus sub-second values.53	 */54	if (src.centiseconds < 100 && src.hundredsOfMicroseconds < 100 &&55	    src.microseconds < 100) {56		dest->tv_nsec = 1000 * (src.centiseconds * 10000 +57			src.hundredsOfMicroseconds * 100 + src.microseconds);58	} else {59		dest->tv_nsec = 0;60	}61}62 63void64udf_time_to_disk_stamp(struct timestamp *dest, struct timespec64 ts)65{66	time64_t seconds;67	int16_t offset;68	struct tm tm;69 70	offset = -sys_tz.tz_minuteswest;71 72	dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF));73 74	seconds = ts.tv_sec + offset * 60;75	time64_to_tm(seconds, 0, &tm);76	dest->year = cpu_to_le16(tm.tm_year + 1900);77	dest->month = tm.tm_mon + 1;78	dest->day = tm.tm_mday;79	dest->hour = tm.tm_hour;80	dest->minute = tm.tm_min;81	dest->second = tm.tm_sec;82	dest->centiseconds = ts.tv_nsec / 10000000;83	dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 -84					dest->centiseconds * 10000) / 100;85	dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -86			      dest->hundredsOfMicroseconds * 100);87}88 89/* EOF */90