ietf-nntp Millenium Bug in Stan Barber's NNTP Reference server
Charles Lindsey
chl at clw.cs.man.ac.uk
Sun Jan 2 14:43:37 PST 2000
This will probably affect a lot of CNEWS sites that have clients using
the NEWNEWS command.
The fix below is not thoroughly tested, but is the best that can be
managed on January 2nd.
It would also seem that INN (at least version 1.7.2) does not understand
dates of the form YYYYMMDD, though it seems at first sight to do the
right thing with 000101.
*** date.c.orig Tue Nov 1 06:08:41 1994
--- date.c Sun Jan 2 21:26:58 2000
***************
*** 58,75 ****
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
long
! dtol(date_ascii)
char *date_ascii;
{
char date[32], *date_str;
char *lhs, *rhs;
char temp;
long seconds;
! int year, month, day, hour, mins, secs;
int len, i;
len = strlen(date_ascii);
! if (len != sizeof("yymmddhhmmss")-1)
return (-1);
(void) strcpy(date, date_ascii);
--- 58,77 ----
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
long
! dtol(date_ascii, local)
char *date_ascii;
+ int local;
{
char date[32], *date_str;
char *lhs, *rhs;
char temp;
long seconds;
! int century, year, month, day, hour, mins, secs;
int len, i;
len = strlen(date_ascii);
! if (len != sizeof("yymmddhhmmss")-1
! && len != sizeof("yyyymmddhhmmss")-1)
return (-1);
(void) strcpy(date, date_ascii);
***************
*** 107,113 ****
--- 109,138 ----
month = twodigtoi(lhs);
lhs += 2;
year = twodigtoi(lhs);
+ lhs += 2;
+ if (*lhs != NULL)
+ century = twodigtoi(lhs) * 100;
+ else {
+ struct tm *gmt;
+ #ifdef USG
+ time_t now;
+ (void) time(&now);
+ gmt = local ? localtime(&now) : gmtime(&now);
+ #else /* not USG */
+ struct timeval now;
+
+ (void) gettimeofday(&now, (struct timezone *)NULL);
+ gmt = local ? localtime(&now.tv_sec) : gmtime(&now.tv_sec);
+ #endif /* not USG */
+ if (gmt->tm_year % 100 >= year)
+ century = (gmt->tm_year / 100 +19) * 100;
+ else
+ century = (gmt->tm_year / 100 +18) * 100;
+ /* all of which is quite correct, but a waste of time,
+ because it will break again in 2038 :-( */
+ }
+
if (month < 1 || month > 12 ||
day < 1 || day > 31 ||
mins < 0 || mins > 59 ||
***************
*** 120,126 ****
if (hour < 0 || hour > 23)
return (-1);
seconds = 0;
! year += 1900;
for (i = 1970; i < year; i++)
seconds += dysize(i);
/* Leap year */
--- 145,151 ----
if (hour < 0 || hour > 23)
return (-1);
seconds = 0;
! year += century;
for (i = 1970; i < year; i++)
seconds += dysize(i);
/* Leap year */
***************
*** 144,150 ****
* since the epoch.
*
* Returns: Pointer to static data in the form
! * yymmddhhmmss\0.
*
* Side effects: None.
*/
--- 169,175 ----
* since the epoch.
*
* Returns: Pointer to static data in the form
! * yyyymmddhhmmss\0.
*
* Side effects: None.
*/
***************
*** 158,165 ****
tp = gmtime(&date);
! (void) sprintf(timebuf, "%02d%02d%02d%02d%02d%02d",
! tp->tm_year,
tp->tm_mon + 1, /* 0 to 11??? How silly. */
tp->tm_mday,
tp->tm_hour,
--- 183,190 ----
tp = gmtime(&date);
! (void) sprintf(timebuf, "%04d%02d%02d%02d%02d%02d",
! tp->tm_year + 1900,
tp->tm_mon + 1, /* 0 to 11??? How silly. */
tp->tm_mday,
tp->tm_hour,
*** newgroups.c.orig Sun Jan 2 16:58:08 2000
--- newgroups.c Sun Jan 2 20:55:19 2000
***************
*** 27,33 ****
char *reqlist[2];
if (argc < 3) {
! printf("%d Usage: NEWGROUPS yymmdd hhmmss [\"GMT\"] [<distributions>].\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
return;
--- 27,33 ----
char *reqlist[2];
if (argc < 3) {
! printf("%d Usage: NEWGROUPS [yy]yymmdd hhmmss [\"GMT\"]
[<distributions>].\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
return;
***************
*** 43,51 ****
return;
}
! /* YYMMDD HHMMSS */
! if (strlen(argv[1]) != 6 || strlen(argv[2]) != 6) {
! printf("%d Date/time must be in form YYMMDD HHMMSS.\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
(void) fclose(date_fp);
--- 43,52 ----
return;
}
! /* [YY]YYMMDD HHMMSS */
! if ((strlen(argv[1]) != 6 && strlen(argv[1]) != 8)
! || strlen(argv[2]) != 6) {
! printf("%d Date/time must be in form [YY]YYMMDD HHMMSS.\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
(void) fclose(date_fp);
***************
*** 52,76 ****
return;
}
! (void) strcpy(line, argv[1]); /* yymmdd */
(void) strcat(line, argv[2]); /* hhmmss */
- date = dtol(line);
- if (date < 0) {
- printf("%d Invalid date specification.\r\n", ERR_CMDSYN);
- (void) fflush(stdout);
- (void) fclose(date_fp);
- return;
- }
-
argc -= 3;
argv += 3;
if (argc > 0 && !strcasecmp(*argv, "GMT")) { /* We store stuff in GMT */
++argv; /* anyway, so this is */
--argc; /* a "noop" */
! } else /* But that means not GMT */
date = local_to_gmt(date); /* is a definite "op" */
if (argc > 0) {
distcount = get_distlist(&dist_list, *argv);
--- 53,78 ----
return;
}
! (void) strcpy(line, argv[1]); /* [yy]yymmdd */
(void) strcat(line, argv[2]); /* hhmmss */
argc -= 3;
argv += 3;
if (argc > 0 && !strcasecmp(*argv, "GMT")) { /* We store stuff in GMT */
+ date = dtol(line, 0);
++argv; /* anyway, so this is */
--argc; /* a "noop" */
! } else { /* But that means not GMT */
! date = dtol(line, 1);
date = local_to_gmt(date); /* is a definite "op" */
+ }
+ if (date < 0) {
+ printf("%d Invalid date specification.\r\n", ERR_CMDSYN);
+ (void) fflush(stdout);
+ (void) fclose(date_fp);
+ return;
+ }
if (argc > 0) {
distcount = get_distlist(&dist_list, *argv);
*** newnews.c.orig Sun Jan 2 16:58:37 2000
--- newnews.c Sun Jan 2 17:00:12 2000
***************
*** 43,49 ****
#endif
if (argc < 4) {
! printf("%d Usage: NEWNEWS newsgroups yymmdd hhmmss [\"GMT\"]
[<distributions>].\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
return;
--- 43,49 ----
#endif
if (argc < 4) {
! printf("%d Usage: NEWNEWS newsgroups [yy]yymmdd hhmmss [\"GMT\"]
[<distributions>].\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
return;
***************
*** 78,86 ****
}
}
! /* YYMMDD HHMMSS */
! if (strlen(argv[2]) != 6 || strlen(argv[3]) != 6) {
! printf("%d Date/time must be in form YYMMDD HHMMSS.\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
return;
--- 78,87 ----
}
}
! /* [YY]YYMMDD HHMMSS */
! if ((strlen(argv[2]) != 6 && strlen(argv[2]) != 8)
! || strlen(argv[3]) != 6) {
! printf("%d Date/time must be in form [YY]YYMMDD HHMMSS.\r\n",
ERR_CMDSYN);
(void) fflush(stdout);
return;
***************
*** 92,99 ****
argc -= 4;
argv += 4;
! key = datebuf; /* Unless they specify GMT */
! date = dtol(datebuf);
if (date < 0) {
printf("%d Invalid date specification.\r\n",ERR_CMDSYN);
(void) fflush(stdout);
--- 93,106 ----
argc -= 4;
argv += 4;
! if (argc > 0 && !strcasecmp(*argv, "GMT")) { /* Which we handle here */
! date = dtol(datebuf, 0);
! date = gmt_to_local(date);
! ++argv;
! --argc;
! } else {
! date = dtol(datebuf, 1);
! }
if (date < 0) {
printf("%d Invalid date specification.\r\n",ERR_CMDSYN);
(void) fflush(stdout);
***************
*** 100,116 ****
return;
}
- if (argc > 0) {
- if (!strcasecmp(*argv, "GMT")) { /* Which we handle here */
- date = gmt_to_local(date);
- ++argv;
- --argc;
- }
- }
/* now we convert from local to GMT since this is what history */
/* file in News 2.11 expects */
date = local_to_gmt(date);
strcpy(datebuf,ltod(date));
distcount = 0;
if (argc > 0) {
distcount = get_distlist(&distlist, *argv);
--- 107,117 ----
return;
}
/* now we convert from local to GMT since this is what history */
/* file in News 2.11 expects */
date = local_to_gmt(date);
strcpy(datebuf,ltod(date));
+ key = datebuf;
distcount = 0;
if (argc > 0) {
distcount = get_distlist(&distlist, *argv);
***************
*** 240,247 ****
* seekuntil -- seek through the history file looking for
* a line with date later than "akey". Get that line, and return.
*
! * Parameters: "fp" is the active file.
! * "akey" is the date, in form YYMMDDHHMMSS
* "line" is storage for the first line we find.
*
* Returns: -1 on error, 0 otherwise.
--- 241,248 ----
* seekuntil -- seek through the history file looking for
* a line with date later than "akey". Get that line, and return.
*
! * Parameters: "fp" is the history file.
! * "akey" is the date, in form YYYYMMDDHHMMSS
* "line" is storage for the first line we find.
*
* Returns: -1 on error, 0 otherwise.
***************
*** 362,367 ****
--- 363,374 ----
* yymmddhhmm (our good one)
* 0123456789 ("x" for w[x])
*/
+
+ /* But it would seem that BNEWS is now totally broke for this millennium,
+ * so no attempt to patch this code has been made, except to say:
+ */
+ return (-1);
+
w[0] = cp[6]; /* Years */
w[1] = cp[7];
w[2] = cp[0]; /* Months */
***************
*** 374,380 ****
w[9] = cp[13];
w[10] = '\0';
}
! else /* convert new format to yymmddhhmmss */
{
long qz;
qz =atol(w);
--- 381,387 ----
w[9] = cp[13];
w[10] = '\0';
}
! else /* convert new format to yyyymmddhhmmss */
{
long qz;
qz =atol(w);
Charles H. Lindsey ---------At Home, doing my own thing------------------------
Email: chl at clw.cs.man.ac.uk Web: http://www.cs.man.ac.uk/~chl
Voice/Fax: +44 161 437 4506 Snail: 5 Clerewood Ave, CHEADLE, SK8 3JU, U.K.
PGP: 2C15F1A9 Fingerprint: 73 6D C2 51 93 A0 01 E7 65 E8 64 7E 14 A4 AB A5
More information about the ietf-nntp
mailing list