Skip site navigation (1)Skip section navigation (2)
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>