Date: Wed, 29 Mar 1995 07:50:03 -0800 From: pritc003@maroon.tc.umn.edu To: freebsd-bugs Subject: kern/283: When using wall CMOS clock, MS-DOS file timestamps are off Message-ID: <199503291550.HAA04266@freefall.cdrom.com> In-Reply-To: Your message of Wed, 29 Mar 1995 09:34:56 -0600 <199503291534.JAA00331@mpp.com>
index | next in thread | previous in thread | raw e-mail
>Number: 283
>Category: kern
>Synopsis: When using wall CMOS clock, MS-DOS file timestamps are off
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs (FreeBSD bugs mailing list)
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Mar 29 07:50:01 1995
>Originator: Mike Pritchard
>Organization:
Mike Pritchard
>Release: FreeBSD 2.1.0-Development i386
>Environment:
Using a wall CMOS clock.
>Description:
If you are using a wall CMOS clock as opposed to a UTC CMOS clock,
the file timestamps on MS-DOS mounted file system are off by the
amount of your timezone adjustment.
>How-To-Repeat:
Mount a MS-DOS file system while using a wall CMOS clock and do an
"ls -l" on some file. Then boot MS-DOS and compare the timestamps.
>Fix:
The supplied patch fixes the problem, as well as optimizes the
dos2unixtime() routine a to eliminate some needless loops in the
code. The unix2dostime() routine could probably also be optimized
a bit, but it probably only gets called 1/100th as much as the other
routine so I didn't bother.
This patch applies to the following revision of msdosfs_conv.c:
/* $Id: msdosfs_conv.c,v 1.3 1994/12/12 12:35:42 bde Exp $ */
*** orig/msdosfs_conv.c Wed Mar 29 07:14:46 1995
--- ./msdosfs_conv.c Wed Mar 29 09:04:26 1995
***************
*** 24,29 ****
--- 24,30 ----
#include <sys/time.h>
#include <sys/kernel.h> /* defines tz */
#include <sys/systm.h> /* defines tz */
+ #include <machine/clock.h>
/*
* MSDOSFS include files.
***************
*** 31,49 ****
#include <msdosfs/direntry.h>
/*
! * Days in each month in a regular year.
*/
u_short regyear[] = {
! 31, 28, 31, 30, 31, 30,
! 31, 31, 30, 31, 30, 31
};
/*
! * Days in each month in a leap year.
*/
u_short leapyear[] = {
! 31, 29, 31, 30, 31, 30,
! 31, 31, 30, 31, 30, 31
};
/*
--- 32,50 ----
#include <msdosfs/direntry.h>
/*
! * Total number of days that have passed for each month in a regular year.
*/
u_short regyear[] = {
! 31, 59, 90, 120, 151, 181,
! 212, 243, 273, 304, 334, 365
};
/*
! * Total number of days that have passed for each month in a leap year.
*/
u_short leapyear[] = {
! 31, 60, 91, 121, 152, 182,
! 213, 244, 274, 305, 335, 366
};
/*
***************
*** 76,82 ****
* If the time from the last conversion is the same as now, then
* skip the computations and use the saved result.
*/
! t = tsp->ts_sec - (tz.tz_minuteswest * 60)
/* +- daylight savings time correction */ ;
if (lasttime != t) {
lasttime = t;
--- 77,83 ----
* If the time from the last conversion is the same as now, then
* skip the computations and use the saved result.
*/
! t = tsp->ts_sec - (tz.tz_minuteswest * 60) - adjkerntz;
/* +- daylight savings time correction */ ;
if (lasttime != t) {
lasttime = t;
***************
*** 99,109 ****
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);
/*
--- 100,109 ----
days -= inc;
}
months = year & 0x03 ? regyear : leapyear;
! for (month = 0; days > months[month]; month++)
! ;
! if (month > 0)
! days -= months[month - 1];
lastddate = ((days + 1) << DD_DAY_SHIFT)
+ ((month + 1) << DD_MONTH_SHIFT);
/*
***************
*** 157,185 ****
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(
"dos2unixtime(): month value out of range (%ld)\n",
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->ts_sec = seconds + lastseconds + (tz.tz_minuteswest * 60)
! /* -+ daylight savings time correction */ ;
tsp->ts_nsec = 0;
}
--- 157,181 ----
lastdosdate = dd;
days = 0;
year = (dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT;
! days = year * 365;
! days += year / 4 + 1; /* add in leap days */
! if ((year & 0x03) == 0)
! days--; /* if year is a leap year */
months = year & 0x03 ? regyear : leapyear;
month = (dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT;
! if (month < 1 || month > 12) {
printf(
"dos2unixtime(): month value out of range (%ld)\n",
month);
month = 1;
}
! if (month > 1)
! days += months[month - 2];
days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1;
lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980;
}
tsp->ts_sec = seconds + lastseconds + (tz.tz_minuteswest * 60)
! + adjkerntz /* -+ daylight savings time correction */ ;
tsp->ts_nsec = 0;
}
>Audit-Trail:
>Unformatted:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199503291550.HAA04266>
