Subject: pkg/9092: Y2K bug in dclock
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kre@munnari.OZ.AU>
List: netbsd-bugs
Date: 12/31/1999 16:21:53
>Number: 9092
>Category: pkg
>Synopsis: dclock shows a malformed date (19?0) in Y2K
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager (NetBSD software packages system bug manager)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Dec 31 16:20:59 1999
>Last-Modified:
>Originator: Robert Elz
>Organization:
University of Melbourne
>Release: NetBSD-current 2000-01-01
>Environment:
System: NetBSD fuchsia.home.cs.mu.OZ.AU 1.4.1 NetBSD 1.4.1 (FUCHSIA) #2: Sat Dec 4 05:28:12 EST 1999 kre@fuchsia.home.cs.mu.OZ.AU:/a/src/sys/arch/i386/compile/FUCHSIA i386
>Description:
The Dclock widget has "19" built in as the century, and
simply does ((year / 10) + '0') to get the tens digit.
Neither is correct in the year 2000 or beyond.
>How-To-Repeat:
Run dclock (showing the date) after 23:59:59 1999-12-31
>Fix:
Replace patch-ab with the following, and replace the line
in patch-sum with
MD5 (patch-ab) = f16a86beb1e9922c19d7634c19cc0ec0
--- Dclock.c.orig Sat Jan 1 10:53:46 2000
+++ Dclock.c Sat Jan 1 11:01:13 2000
@@ -21,8 +21,6 @@
#define CLOCK_WIDTH 256
#define CLOCK_HEIGHT 80
#define DATE_FMT "%W, %M %d"
-#define when break;case
-#define otherwise break;default
static Boolean SetValues(), show_time();
@@ -367,8 +365,8 @@
if (w->dclock.interval_id != (XtIntervalId)NULL)
XtRemoveTimeOut(w->dclock.interval_id);
- XtReleaseGC (w, w->dclock.foreGC);
- XtReleaseGC (w, w->dclock.backGC);
+ XtReleaseGC ((Widget) w, w->dclock.foreGC);
+ XtReleaseGC ((Widget) w, w->dclock.backGC);
for (n = 0; n < 10; n++) {
XFreePixmap(XtDisplay(w), w->dclock.digits[n]);
XFreePixmap(XtDisplay(w), w->dclock.tiny_digits[n]);
@@ -388,7 +386,7 @@
Pixmap pix;
GC gc = w->dclock.foreGC;
- if (!XtIsRealized(w))
+ if (!XtIsRealized((Widget) w))
return;
winwidth = w->core.width;
@@ -450,7 +448,7 @@
make_number(w, w->dclock.tiny_digits[i], gc, i, tiny_segment_pts);
}
else
- w->dclock.tiny_digits[i] = NULL;
+ (Widget) w->dclock.tiny_digits[i] = (Pixmap) NULL;
}
/* The colon[0] area is blank */
if (w->dclock.colon[0])
@@ -629,7 +627,7 @@
Boolean save_fade = w->dclock.fade;
long t;
- if (!XtIsRealized(w))
+ if (!XtIsRealized((Widget) w))
return;
if (w->dclock.interval_id != (XtIntervalId)NULL) {
@@ -802,7 +800,7 @@
turn_off[i] = oldmask & ~newmask;
}
else
- tmp_pix[i] = NULL;
+ tmp_pix[i] = (Pixmap) NULL;
for (j = 1; j != FADE_ITER; ++j)
{
@@ -869,36 +867,47 @@
register char *datep = datestr, *p;
int x;
+ now->tm_year += 1900;
if (!w->dclock.display_time)
datep += strlen(strcpy(datep, "Push HERE to Set/Unset Alarm"));
else for (p = w->dclock.date_fmt; p && *p; p++) {
if (*p != '%')
*datep++ = *p;
else switch (*++p) {
- when 'M':
+ case 'M':
datep += strlen(strcpy(datep, Months[now->tm_mon]));
- when 'm':
+ break;
+ case 'm':
datep += strlen(strcpy(datep, months[now->tm_mon]));
- when 'W':
+ break;
+ case 'W':
datep += strlen(strcpy(datep, Days[now->tm_wday]));
- when 'w':
+ break;
+ case 'w':
datep += strlen(strcpy(datep, days[now->tm_wday]));
- when 'd':
+ break;
+ case 'd':
if (now->tm_mday >= 10)
*datep++ = (now->tm_mday / 10 + '0');
*datep++ = now->tm_mday % 10 + '0';
- when 'Y':
- *datep++ = '1', *datep++ = '9';
- /* fall thru */
+ break;
+ case 'Y':
+ *datep++ = (now->tm_year / 1000) + '0';
+ *datep++ = ((now->tm_year / 100) % 10) + '0';
+ /* FALLTHROUGH */
case 'y':
- *datep++ = now->tm_year / 10 + '0';
- *datep++ = now->tm_year % 10 + '0';
- when '%':
+ *datep++ = ((now->tm_year / 10) % 10) + '0';
+ *datep++ = (now->tm_year % 10) + '0';
+ break;
+ case '%':
*datep++ = *p;
- otherwise: ; /* nothing */
+ break;
+ default:
+ break; /* nothing */
}
}
*datep = 0;
+ now->tm_year -= 1900;
x = (w->core.width - XTextWidth(w->dclock.font, datestr, datep-datestr))/2;
if (x < 2)
@@ -906,7 +915,7 @@
/* remove what was there in case the whole thing isn't overwritten */
XFillRectangle(XtDisplay(w), XtWindow(w), w->dclock.backGC,
- 0, winheight - (w->dclock.font->ascent + w->dclock.font->descent),
+ 0, winheight - (w->dclock.font->ascent + BORDER),
winwidth, w->dclock.font->ascent + w->dclock.font->descent);
XDrawString(XtDisplay(w), XtWindow(w), w->dclock.foreGC,
@@ -924,7 +933,8 @@
{
Boolean alarm_went_off = show_time(w);
w->dclock.interval_id =
- XtAddTimeOut((unsigned long)((alarm_went_off || w->dclock.seconds)? 1000 : 60000),
+ XtAddTimeOut((unsigned long)((alarm_went_off || w->dclock.seconds) ?
+ 1000 : 60000 - ((time(0L) % 60) * 1000)),
timeout, (XtPointer)w);
}
@@ -960,8 +970,8 @@
|| new->dclock.tails != current->dclock.tails
|| new->dclock.fade != current->dclock.fade
|| new->dclock.miltime != current->dclock.miltime) {
- XtReleaseGC (current, current->dclock.foreGC);
- XtReleaseGC (current, current->dclock.backGC);
+ XtReleaseGC ((Widget) current, current->dclock.foreGC);
+ XtReleaseGC ((Widget) current, current->dclock.backGC);
GetGC(new);
Resize(new); /* pixmaps need to be redrawn */
do_redraw = True;
@@ -1024,7 +1034,7 @@
Arg arg;
XtSetArg(arg, XtNreverseVideo, !w->dclock.reverse);
- XtSetValues(w, &arg, 1);
+ XtSetValues((Widget) w, &arg, 1);
}
static void
@@ -1038,7 +1048,7 @@
return;
}
XtSetArg(arg, XtNmilitaryTime, !w->dclock.miltime);
- XtSetValues(w, &arg, 1);
+ XtSetValues((Widget) w, &arg, 1);
}
static void
@@ -1052,7 +1062,7 @@
return;
}
XtSetArg(arg, XtNseconds, !w->dclock.seconds);
- XtSetValues(w, &arg, 1);
+ XtSetValues((Widget) w, &arg, 1);
}
static void
@@ -1062,7 +1072,7 @@
Arg arg;
XtSetArg(arg, XtNfade, !w->dclock.fade);
- XtSetValues(w, &arg, 1);
+ XtSetValues((Widget) w, &arg, 1);
if (w->dclock.fade && w->dclock.scroll)
toggle_scroll(w);
}
@@ -1074,7 +1084,7 @@
Arg arg;
XtSetArg(arg, XtNtails, !w->dclock.tails);
- XtSetValues(w, &arg, 1);
+ XtSetValues((Widget) w, &arg, 1);
}
static void
@@ -1084,7 +1094,7 @@
Arg arg;
XtSetArg(arg, XtNalarm, !w->dclock.alarm);
- XtSetValues(w, &arg, 1);
+ XtSetValues((Widget) w, &arg, 1);
}
static void
@@ -1124,20 +1134,24 @@
int digit = w->dclock.alarm_time[i>1?i+1:i] - '0';
int mod;
switch (i) {
- when 0:
+ case 0:
if (Alarm.hrs > 13 && digit == 1)
digit++;
mod = 3;
before.tm_hour = -1;
- when 1 :
+ break;
+ case 1 :
mod = (Alarm.hrs < 20)? 10 : 4;
before.tm_hour = -1;
- when 2:
+ break;
+ case 2:
mod = 6;
before.tm_min = -1;
- when 3 :
+ break;
+ case 3 :
mod = 10;
before.tm_min = -1;
+ break;
}
if (event->button == 1)
digit = (digit + 1) % mod;
>Audit-Trail:
>Unformatted: