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