File: fetchnews_check_date.c

package info (click to toggle)
leafnode 1.11.11-1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 2,468 kB
  • sloc: ansic: 10,914; sh: 1,748; xml: 628; makefile: 291; perl: 84; sed: 4
file content (76 lines) | stat: -rw-r--r-- 2,307 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "leafnode.h"

#include <string.h>

#include "fetchnews.h"
#include "system.h"
#include "ln_log.h"

/* send DATE command to upstream server and complain if the clocks are
 * more than 15 minutes apart.
 */
void
check_date(const struct server *current_server)
{
    int reply;
    struct tm tm;
    time_t t, to;
    const int tolerate = 10;
    const char *lastline;

    strcpy(lineout, "DATE\r\n");
    putaline();
    reply = nntpreply(current_server);
    if (reply != 111) {
	/* upstream does not support the DATE command, so ignore */
	if (debugmode) {
	    syslog(LOG_DEBUG, "check_date: %s: does not support DATE, "
		    "reply %d, expected 111", current_server->name, reply);
	}
	return;
    }

    lastline = lastreply();
    if (lastline == NULL) {
	ln_log(LNLOG_SWARNING, LNLOG_CTOP,
		"%s: warning: server disconnect or timeout in response to DATE command",
		current_server->name);
	return;
    }

    /* upstream supports the DATE command */
    if (sscanf(lastline, "%*d %4d%2d%2d%2d%2d%2d",
		&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
		&tm.tm_hour, &tm.tm_min, &tm.tm_sec) < 6) {
	/* too few fields */
	ln_log(LNLOG_SINFO, LNLOG_CSERVER, "%s: check_date: too few fields in successful DATE reply "
		"\"%s\"", current_server->name, lastline);
	return;
    }

    /* we can match 6 fields, parse date */
    tm.tm_year -= 1900;
    tm.tm_mon -= 1;
    tm.tm_isdst = -1; /* let libc figure time zone offset */
    t = timegm(&tm);
    if (t == (time_t) -1) {
	/* error, ignore */
	ln_log(LNLOG_SINFO, LNLOG_CSERVER, "%s: check_date: upstream sent unparsable reply "
		"to DATE, mktime failed. \"%s\"", current_server->name, lastline);
	return;
    }

    if (labs((long)(t - time(&to))) > tolerate * 60
#if SIZEOF_TIME_T >= SIZEOF_LONG
		    || t - to > LONG_MAX || to - t > LONG_MAX
#endif
		    ) {
	syslog(LOG_WARNING, "check_date: %s: clocks of upstream and this computer are more than %d minutes apart. Check your system clock.", current_server->name, tolerate);
	printf("check_date: %s: clocks of upstream and this computer are more than\n%d minutes apart. Check your system clock.\n", current_server->name, tolerate);
    } else {
	if (debugmode) {
	    syslog(LOG_DEBUG, "check_date: %s: server time %ld, our time %ld",
		    current_server->name, (long)t, (long)to);
	}
    }
}