summaryrefslogtreecommitdiffstats
path: root/usr.sbin/newsyslog
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2003-09-14 00:56:50 +0000
committergad <gad@FreeBSD.org>2003-09-14 00:56:50 +0000
commit1974e185f819a3a3f128a6636a46deef6f289afd (patch)
tree2c2b601037a58de61095e7665a7c77fc13a4b128 /usr.sbin/newsyslog
parent430e8af1657c740b966e30a8585dcbccedf73273 (diff)
downloadFreeBSD-src-1974e185f819a3a3f128a6636a46deef6f289afd.zip
FreeBSD-src-1974e185f819a3a3f128a6636a46deef6f289afd.tar.gz
Correct the calculation of "a leap year" in parseDWM. The calculation
would only match a leap year every 400 years. The parseDWM code first showed up in April 2000, so the first time this bug would cause any confusion is in Feb 2004. MFC after: 18 days
Diffstat (limited to 'usr.sbin/newsyslog')
-rw-r--r--usr.sbin/newsyslog/ptimes.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/usr.sbin/newsyslog/ptimes.c b/usr.sbin/newsyslog/ptimes.c
index c00b08c..46fe1c7 100644
--- a/usr.sbin/newsyslog/ptimes.c
+++ b/usr.sbin/newsyslog/ptimes.c
@@ -48,6 +48,42 @@ __FBSDID("$FreeBSD$");
#include "extern.h"
+static int days_pmonth(int month, int year);
+
+/*
+ * Simple routine to calculate the number of days in a given month.
+ */
+static int
+days_pmonth(int month, int year)
+{
+ static const int mtab[] = {31, 28, 31, 30, 31, 30, 31, 31,
+ 30, 31, 30, 31};
+ int ndays;
+
+ ndays = mtab[month];
+
+ if (month == 1) {
+ /*
+ * We are usually called with a 'tm-year' value
+ * (ie, the value = the number of years past 1900).
+ */
+ if (year < 1900)
+ year += 1900;
+ if (year % 4 == 0) {
+ /*
+ * This is a leap year, as long as it is not a
+ * multiple of 100, or if it is a multiple of
+ * both 100 and 400.
+ */
+ if (year % 100 != 0)
+ ndays++; /* not multiple of 100 */
+ else if (year % 400 == 0)
+ ndays++; /* is multiple of 100 and 400 */
+ }
+ }
+ return (ndays);
+}
+
/*-
* Parse a limited subset of ISO 8601. The specific format is as follows:
*
@@ -158,12 +194,11 @@ parse8601(const char *s, time_t *next_time)
time_t
parseDWM(char *s, time_t *next_time)
{
+ int daysmon;
char *t;
time_t tsecs;
struct tm tm, *tmp;
long l;
- int nd;
- static int mtab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int WMseen = 0;
int Dseen = 0;
@@ -172,17 +207,8 @@ parseDWM(char *s, time_t *next_time)
if (next_time != NULL)
*next_time = (time_t)-1;
- /* set no. of days per month */
-
- nd = mtab[tm.tm_mon];
-
- if (tm.tm_mon == 1) {
- if (((tm.tm_year + 1900) % 4 == 0) &&
- ((tm.tm_year + 1900) % 100 != 0) &&
- ((tm.tm_year + 1900) % 400 == 0)) {
- nd++; /* leap year, 29 days in february */
- }
- }
+ /* Save away the number of days in this month */
+ daysmon = days_pmonth(tm.tm_mon, tm.tm_year);
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
for (;;) {
@@ -218,9 +244,9 @@ parseDWM(char *s, time_t *next_time)
tm.tm_mday += save;
- if (tm.tm_mday > nd) {
+ if (tm.tm_mday > daysmon) {
tm.tm_mon++;
- tm.tm_mday = tm.tm_mday - nd;
+ tm.tm_mday = tm.tm_mday - daysmon;
}
}
break;
@@ -231,7 +257,7 @@ parseDWM(char *s, time_t *next_time)
WMseen++;
s++;
if (tolower(*s) == 'l') {
- tm.tm_mday = nd;
+ tm.tm_mday = daysmon;
s++;
t = s;
} else {
@@ -239,7 +265,7 @@ parseDWM(char *s, time_t *next_time)
if (l < 1 || l > 31)
return (-1);
- if (l > nd)
+ if (l > daysmon)
return (-1);
tm.tm_mday = l;
}
OpenPOWER on IntegriCloud