Back to home page

OSCL-LXR

 
 

    


0001 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
0002    This file is part of the GNU C Library.
0003    Contributed by Paul Eggert (eggert@twinsun.com).
0004 
0005    The GNU C Library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public License as
0007    published by the Free Software Foundation; either version 2 of the
0008    License, or (at your option) any later version.
0009 
0010    The GNU C Library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public
0016    License along with the GNU C Library; see the file COPYING.LIB.  If not,
0017    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0018    Boston, MA 02111-1307, USA.  */
0019 
0020 /*
0021  * dgb 10/02/98: ripped this from glibc source to help convert timestamps
0022  *               to unix time
0023  *     10/04/98: added new table-based lookup after seeing how ugly
0024  *               the gnu code is
0025  * blf 09/27/99: ripped out all the old code and inserted new table from
0026  *       John Brockmeyer (without leap second corrections)
0027  *       rewrote udf_stamp_to_time and fixed timezone accounting in
0028  *       udf_time_to_stamp.
0029  */
0030 
0031 /*
0032  * We don't take into account leap seconds. This may be correct or incorrect.
0033  * For more NIST information (especially dealing with leap seconds), see:
0034  * http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
0035  */
0036 
0037 #include "udfdecl.h"
0038 
0039 #include <linux/types.h>
0040 #include <linux/kernel.h>
0041 #include <linux/time.h>
0042 
0043 void
0044 udf_disk_stamp_to_time(struct timespec64 *dest, struct timestamp src)
0045 {
0046     u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);
0047     u16 year = le16_to_cpu(src.year);
0048     uint8_t type = typeAndTimezone >> 12;
0049     int16_t offset;
0050 
0051     if (type == 1) {
0052         offset = typeAndTimezone << 4;
0053         /* sign extent offset */
0054         offset = (offset >> 4);
0055         if (offset == -2047) /* unspecified offset */
0056             offset = 0;
0057     } else
0058         offset = 0;
0059 
0060     dest->tv_sec = mktime64(year, src.month, src.day, src.hour, src.minute,
0061             src.second);
0062     dest->tv_sec -= offset * 60;
0063     dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
0064             src.hundredsOfMicroseconds * 100 + src.microseconds);
0065     /*
0066      * Sanitize nanosecond field since reportedly some filesystems are
0067      * recorded with bogus sub-second values.
0068      */
0069     dest->tv_nsec %= NSEC_PER_SEC;
0070 }
0071 
0072 void
0073 udf_time_to_disk_stamp(struct timestamp *dest, struct timespec64 ts)
0074 {
0075     time64_t seconds;
0076     int16_t offset;
0077     struct tm tm;
0078 
0079     offset = -sys_tz.tz_minuteswest;
0080 
0081     dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF));
0082 
0083     seconds = ts.tv_sec + offset * 60;
0084     time64_to_tm(seconds, 0, &tm);
0085     dest->year = cpu_to_le16(tm.tm_year + 1900);
0086     dest->month = tm.tm_mon + 1;
0087     dest->day = tm.tm_mday;
0088     dest->hour = tm.tm_hour;
0089     dest->minute = tm.tm_min;
0090     dest->second = tm.tm_sec;
0091     dest->centiseconds = ts.tv_nsec / 10000000;
0092     dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 -
0093                     dest->centiseconds * 10000) / 100;
0094     dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
0095                   dest->hundredsOfMicroseconds * 100);
0096 }
0097 
0098 /* EOF */