Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Make msdosfs time conversion use the y/m/d/h/m/s conversion ...
details: https://anonhg.NetBSD.org/src/rev/276163714f3b
branches: trunk
changeset: 331938:276163714f3b
user: martin <martin%NetBSD.org@localhost>
date: Mon Sep 01 09:09:47 2014 +0000
description:
Make msdosfs time conversion use the y/m/d/h/m/s conversion functions
from clock_subr.c and compile that into the userland (and tools)
makefs as well.
diffstat:
sys/fs/msdosfs/msdosfs_conv.c | 173 ++++++++++++------------------------
usr.sbin/makefs/msdos/Makefile.inc | 5 +-
2 files changed, 61 insertions(+), 117 deletions(-)
diffs (260 lines):
diff -r 918aa94e2c8d -r 276163714f3b sys/fs/msdosfs/msdosfs_conv.c
--- a/sys/fs/msdosfs/msdosfs_conv.c Mon Sep 01 08:21:26 2014 +0000
+++ b/sys/fs/msdosfs/msdosfs_conv.c Mon Sep 01 09:09:47 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: msdosfs_conv.c,v 1.9 2013/01/26 16:51:51 christos Exp $ */
+/* $NetBSD: msdosfs_conv.c,v 1.10 2014/09/01 09:09:47 martin Exp $ */
/*-
* Copyright (C) 1995, 1997 Wolfgang Solfrank.
@@ -52,7 +52,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.9 2013/01/26 16:51:51 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.10 2014/09/01 09:09:47 martin Exp $");
/*
* System include files.
@@ -66,9 +66,11 @@
#include <sys/vnode.h>
#else
#include <stdio.h>
+#include <string.h>
#include <dirent.h>
#include <sys/queue.h>
#endif
+#include <dev/clock_subr.h>
/*
* MSDOSFS include files.
@@ -77,29 +79,15 @@
#include <fs/msdosfs/denode.h>
/*
- * Days in each month in a regular year.
- */
-u_short const regyear[] = {
- 31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31
-};
-
-/*
- * Days in each month in a leap year.
+ * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
+ * interval there were 8 regular years and 2 leap years.
*/
-u_short const leapyear[] = {
- 31, 29, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31
-};
-
+#define DOSBIASYEAR 1980
+#define SECONDSTO1980 (((8 * 365) + (2 * 366)) * (24 * 60 * 60))
/*
- * Variables used to remember parts of the last time conversion. Maybe we
- * can avoid a full conversion.
+ * msdos fs can not store dates beyound the year 2234
*/
-u_long lasttime;
-u_long lastday;
-u_short lastddate;
-u_short lastdtime;
+#define DOSMAXYEAR ((DD_YEAR_MASK >> DD_YEAR_SHIFT) + DOSBIASYEAR)
/*
* Convert the unix version of time to dos's idea of time to be used in
@@ -109,74 +97,51 @@
unix2dostime(const struct timespec *tsp, int gmtoff, u_int16_t *ddp, u_int16_t *dtp, u_int8_t *dhp)
{
u_long t;
- u_long days;
- u_long inc;
- u_long year;
- u_long month;
- const u_short *months;
+ struct clock_ymdhms ymd;
+
+ t = tsp->tv_sec + gmtoff; /* time zone correction */
+
+ /*
+ * DOS timestamps can not represent dates before 1980.
+ */
+ if (t < SECONDSTO1980)
+ goto invalid_dos_date;
+
+ /*
+ * DOS granularity is 2 seconds
+ */
+ t &= ~1;
/*
- * If the time from the last conversion is the same as now, then
- * skip the computations and use the saved result.
+ * Convert to year/month/day/.. format
*/
- t = tsp->tv_sec + gmtoff; /* time zone correction */
- t &= ~1;
- if (lasttime != t) {
- lasttime = t;
- lastdtime = (((t / 2) % 30) << DT_2SECONDS_SHIFT)
+ clock_secs_to_ymdhms(t, &ymd);
+ if (ymd.dt_year > DOSMAXYEAR)
+ goto invalid_dos_date;
+
+ /*
+ * Now transform to DOS format
+ */
+ *ddp = (ymd.dt_day << DD_DAY_SHIFT)
+ + (ymd.dt_mon << DD_MONTH_SHIFT)
+ + ((ymd.dt_year - DOSBIASYEAR) << DD_YEAR_SHIFT);
+ if (dhp)
+ *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
+ if (dtp)
+ *dtp = (((t / 2) % 30) << DT_2SECONDS_SHIFT)
+ (((t / 60) % 60) << DT_MINUTES_SHIFT)
+ (((t / 3600) % 24) << DT_HOURS_SHIFT);
+ return;
- /*
- * If the number of days since 1970 is the same as the last
- * time we did the computation then skip all this leap year
- * and month stuff.
- */
- days = t / (24 * 60 * 60);
- if (days != lastday) {
- lastday = days;
- for (year = 1970;; year++) {
- inc = year & 0x03 ? 365 : 366;
- if (days < inc)
- break;
- days -= inc;
- }
- months = year & 0x03 ? regyear : leapyear;
- for (month = 0; month < 12; month++) {
- if (days < months[month])
- break;
- days -= months[month];
- }
- lastddate = ((days + 1) << DD_DAY_SHIFT)
- + ((month + 1) << DD_MONTH_SHIFT);
- /*
- * Remember dos's idea of time is relative to 1980.
- * unix's is relative to 1970. If somehow we get a
- * time before 1980 then don't give totally crazy
- * results.
- */
- if (year > 1980)
- lastddate += (year - 1980) << DD_YEAR_SHIFT;
- }
- }
+invalid_dos_date:
+ *ddp = 0;
if (dtp)
- *dtp = lastdtime;
+ *dtp = 0;
if (dhp)
- *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
-
- *ddp = lastddate;
+ *dhp = 0;
}
/*
- * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
- * interval there were 8 regular years and 2 leap years.
- */
-#define SECONDSTO1980 (((8 * 365) + (2 * 366)) * (24 * 60 * 60))
-
-u_short lastdosdate;
-u_long lastseconds;
-
-/*
* Convert from dos' idea of time to unix'. This will probably only be
* called from the stat(), and fstat() system calls and so probably need
* not be too efficient.
@@ -184,11 +149,8 @@
void
dos2unixtime(u_int dd, u_int dt, u_int dh, int gmtoff, struct timespec *tsp)
{
- u_long seconds;
- u_long m, month;
- u_long y, year;
- u_long days;
- const u_short *months;
+ time_t seconds;
+ struct clock_ymdhms ymd;
if (dd == 0) {
/*
@@ -198,37 +160,18 @@
tsp->tv_nsec = 0;
return;
}
- seconds = ((dt & DT_2SECONDS_MASK) >> DT_2SECONDS_SHIFT) * 2
- + ((dt & DT_MINUTES_MASK) >> DT_MINUTES_SHIFT) * 60
- + ((dt & DT_HOURS_MASK) >> DT_HOURS_SHIFT) * 3600
- + dh / 100;
- /*
- * If the year, month, and day from the last conversion are the
- * same then use the saved value.
- */
- if (lastdosdate != dd) {
- lastdosdate = dd;
- days = 0;
- year = (dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT;
- for (y = 0; y < year; y++)
- days += y & 0x03 ? 365 : 366;
- months = year & 0x03 ? regyear : leapyear;
- /*
- * Prevent going from 0 to 0xffffffff in the following
- * loop.
- */
- month = (dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT;
- if (month == 0) {
- printf("%s: month value out of range (%ld)\n",
- __func__, month);
- month = 1;
- }
- for (m = 0; m < month - 1; m++)
- days += months[m];
- days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1;
- lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980;
- }
- tsp->tv_sec = seconds + lastseconds;
+
+ memset(&ymd, 0, sizeof(ymd));
+ ymd.dt_year = ((dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT) + 1980 ;
+ ymd.dt_mon = ((dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT);
+ ymd.dt_day = ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT);
+ ymd.dt_hour = (dt & DT_HOURS_MASK) >> DT_HOURS_SHIFT;
+ ymd.dt_min = (dt & DT_MINUTES_MASK) >> DT_MINUTES_SHIFT;
+ ymd.dt_sec = ((dt & DT_2SECONDS_MASK) >> DT_2SECONDS_SHIFT) * 2;
+
+ seconds = clock_ymdhms_to_secs(&ymd);
+
+ tsp->tv_sec = seconds;
tsp->tv_sec -= gmtoff; /* time zone correction */
tsp->tv_nsec = (dh % 100) * 10000000;
}
diff -r 918aa94e2c8d -r 276163714f3b usr.sbin/makefs/msdos/Makefile.inc
--- a/usr.sbin/makefs/msdos/Makefile.inc Mon Sep 01 08:21:26 2014 +0000
+++ b/usr.sbin/makefs/msdos/Makefile.inc Mon Sep 01 09:09:47 2014 +0000
@@ -1,10 +1,10 @@
-# $NetBSD: Makefile.inc,v 1.5 2013/01/26 16:50:46 christos Exp $
+# $NetBSD: Makefile.inc,v 1.6 2014/09/01 09:09:47 martin Exp $
#
MSDOS= ${NETBSDSRCDIR}/sys/fs/msdosfs
MSDOS_NEWFS= ${NETBSDSRCDIR}/sbin/newfs_msdos
-.PATH: ${.CURDIR}/msdos ${MSDOS} ${MSDOS_NEWFS}
+.PATH: ${.CURDIR}/msdos ${MSDOS} ${MSDOS_NEWFS} ${NETBSDSRCDIR}/sys/dev
CPPFLAGS+= -DMSDOS_EI -I${MSDOS} -I${MSDOS_NEWFS}
.if !defined(HOSTPROGNAME)
@@ -13,3 +13,4 @@
SRCS+= mkfs_msdos.c msdosfs_fat.c msdosfs_conv.c msdosfs_vfsops.c
SRCS+= msdosfs_lookup.c msdosfs_denode.c msdosfs_vnops.c
+SRCS+= clock_subr.c
Home |
Main Index |
Thread Index |
Old Index