86 lines
2.8 KiB
Diff
86 lines
2.8 KiB
Diff
From 607fbed2534cb80063395936384f4aef293812fd Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com>
|
|
Date: Tue, 14 Aug 2018 20:57:27 +0200
|
|
Subject: [PATCH 72/86] fsck.fat: Fix Year 2038 Bug
|
|
|
|
Do not use time_t type and strftime() function which are affected by the
|
|
Year 2038 Bug. Instead parse date/time directly from DOS format which
|
|
avoids conversion from DOS to UNIX + conversion from UNIX to string.
|
|
---
|
|
src/check.c | 55 +++++++++++++++++++++----------------------------------
|
|
1 file changed, 21 insertions(+), 34 deletions(-)
|
|
|
|
diff --git a/src/check.c b/src/check.c
|
|
index 13a5fd6..76e9721 100644
|
|
--- a/src/check.c
|
|
+++ b/src/check.c
|
|
@@ -108,44 +108,31 @@ static char *path_name(DOS_FILE * file)
|
|
return path;
|
|
}
|
|
|
|
-static const int day_n[] =
|
|
- { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 };
|
|
-/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
|
|
-
|
|
-/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
|
|
-
|
|
-static time_t date_dos2unix(unsigned short time, unsigned short date)
|
|
-{
|
|
- int month, year;
|
|
- time_t secs;
|
|
-
|
|
- month = ((date >> 5) & 15) - 1;
|
|
- if (month < 0) {
|
|
- /* make sure that nothing bad happens if the month bits were zero */
|
|
- month = 0;
|
|
- }
|
|
- year = date >> 9;
|
|
- secs =
|
|
- (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
|
|
- 86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 -
|
|
- ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653);
|
|
- /* days since 1.1.70 plus 80's leap day */
|
|
- return secs;
|
|
-}
|
|
+static const char *month_str[] =
|
|
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
|
|
|
static char *file_stat(DOS_FILE * file)
|
|
{
|
|
static char temp[100];
|
|
- struct tm *tm;
|
|
- char tmp[40];
|
|
- time_t date;
|
|
-
|
|
- date =
|
|
- date_dos2unix(le16toh(file->dir_ent.time), le16toh(file->dir_ent.date));
|
|
- tm = localtime(&date);
|
|
- if (!strftime(tmp, 40, "%H:%M:%S %b %d %Y", tm))
|
|
- strcpy(tmp, "<internal format error>");
|
|
- sprintf(temp, " Size %u bytes, date %s", le32toh(file->dir_ent.size), tmp);
|
|
+ unsigned int hours, minutes, secs, day, month, year;
|
|
+ unsigned short time, date;
|
|
+
|
|
+ time = le16toh(file->dir_ent.time);
|
|
+ date = le16toh(file->dir_ent.date);
|
|
+ year = 1980 + (date >> 9);
|
|
+ month = ((date >> 5) & 15);
|
|
+ if (month < 1) month = 1;
|
|
+ else if (month > 12) month = 12;
|
|
+ day = (date & 31);
|
|
+ if (day < 1) day = 1;
|
|
+ hours = (time >> 11);
|
|
+ if (hours > 23) hours = 23;
|
|
+ minutes = ((time >> 5) & 63);
|
|
+ if (minutes > 59) minutes = 59;
|
|
+ secs = (time & 31) * 2;
|
|
+ if (secs > 59) secs = 59;
|
|
+ sprintf(temp, " Size %u bytes, date %02u:%02u:%02u %s %02u %4u",
|
|
+ le32toh(file->dir_ent.size), hours, minutes, secs, month_str[month-1], day, year);
|
|
return temp;
|
|
}
|
|
|
|
--
|
|
1.8.3.1
|
|
|