Download raw body.
newsyslog: refactor date parsing
Hi all,
analogue to rev1.118 [1], I refactored parseDWM() in newsyslog(8) for date parsing.
I replaced the manual parsing with strtol(3) by strptime(3).
Best regards
Nico
[1]: https://cvsweb.openbsd.org/log/src/usr.bin/newsyslog/newsyslog.c,v?sort=File#rev1.118
Index: newsyslog.c
===================================================================
RCS file: /cvs/src/usr.bin/newsyslog/newsyslog.c,v
diff -u -p -r1.120 newsyslog.c
--- newsyslog.c 2 Apr 2026 18:22:24 -0000 1.120
+++ newsyslog.c 20 Apr 2026 13:17:33 -0000
@@ -1239,10 +1239,10 @@ time_t
parseDWM(char *s)
{
static int mtab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- int WMseen = 0, Dseen = 0, nd;
- struct tm tm;
- char *t;
- long l;
+ int nd;
+ char format[7] = { 0 };
+ struct tm tm, now;
+ char *d, *w, *m;
if (localtime_r(&timenow, &tm) == NULL)
return -1;
@@ -1259,79 +1259,49 @@ parseDWM(char *s)
}
}
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ memcpy(&now, &tm, sizeof tm);
- for (;;) {
- switch (*s) {
- case 'D':
- if (Dseen)
- return (-1);
- Dseen++;
- s++;
- l = strtol(s, &t, 10);
- if (l < 0 || l > 23)
- return (-1);
- tm.tm_hour = l;
- break;
-
- case 'W':
- if (WMseen)
- return (-1);
- WMseen++;
- s++;
- l = strtol(s, &t, 10);
- if (l < 0 || l > 6)
- return (-1);
- if (l != tm.tm_wday) {
- int save;
-
- if (l < tm.tm_wday) {
- save = 6 - tm.tm_wday;
- save += (l + 1);
- } else {
- save = l - tm.tm_wday;
- }
-
- tm.tm_mday += save;
-
- if (tm.tm_mday > nd) {
- tm.tm_mon++;
- tm.tm_mday = tm.tm_mday - nd;
- }
- }
- break;
-
- case 'M':
- if (WMseen)
- return (-1);
- WMseen++;
- s++;
- if (tolower((unsigned char)*s) == 'l') {
- tm.tm_mday = nd;
- s++;
- t = s;
- } else {
- l = strtol(s, &t, 10);
- if (l < 1 || l > 31)
- return (-1);
-
- if (l > nd)
- return (-1);
- if (l < tm.tm_mday)
- tm.tm_mon++;
- tm.tm_mday = l;
- }
- break;
-
- default:
- return (-1);
- break;
- }
+ m = strchr(s, 'M');
+ w = strchr(s, 'W');
+ d = strchr(s, 'D');
+
+ if (m != NULL && w != NULL)
+ return -1;
- if (*t == '\0' || isspace((unsigned char)*t))
- break;
+ if ((m != NULL && w == NULL) && s == m) {
+ if (tolower(m[1]) == 'l') {
+ tm.tm_mday = nd;
+ snprintf(format, sizeof format, "M%c", m[1]);
+ s = d;
+ } else {
+ strlcat(format, "M%e", sizeof format);
+ }
+ } else if ((w != NULL && m == NULL) && s == w) {
+ strlcat(format, "W%w", sizeof format);
+ } else if (d != s)
+ return (-1);
+
+ if (d != NULL)
+ strlcat(format, "D%H", sizeof format);
+
+ if (strptime(s, format, &tm) == NULL)
+ return (-1);
+
+ if (tm.tm_wday != now.tm_wday) {
+ if (now.tm_wday > tm.tm_wday)
+ tm.tm_mday += 7 - (now.tm_wday - tm.tm_wday);
else
- s = t;
+ tm.tm_mday += tm.tm_wday - now.tm_wday;
+
+ if (tm.tm_mday > nd) {
+ tm.tm_mday -= nd;
+ tm.tm_mon++;
+ }
}
+
+ if (now.tm_mday > tm.tm_mday)
+ tm.tm_mon++;
+
return (mktime(&tm));
}
newsyslog: refactor date parsing