diff --git a/usr.sbin/newsyslog/ptimes.c b/usr.sbin/newsyslog/ptimes.c index c00b08c55e86..46fe1c7c0e52 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; }