"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "htpdate.c" between
htpdate-1.3.3.tar.gz and htpdate-1.3.4.tar.gz

About: HTPdate (HTTP Time Protocol) synchronizes a computer’s time with web servers as reference time source (working through proxy servers).

htpdate.c  (htpdate-1.3.3):htpdate.c  (htpdate-1.3.4)
/* /*
htpdate v1.3.3 htpdate v1.3.4
Eddy Vervest <eddy@vervest.org> Eddy Vervest <eddy@vervest.org>
http://www.vervest.org/htp http://www.vervest.org/htp
Synchronize local system with time offered by remote web servers Synchronize local system with time offered by remote web servers
This program works with the timestamps return by web servers, This program works with the timestamps return by web servers,
formatted as specified by HTTP/1.1 (RFC 2616, RFC 1123). formatted as specified by HTTP/1.1 (RFC 2616, RFC 1123).
Example usage: Example usage:
skipping to change at line 53 skipping to change at line 53
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/timex.h> #include <sys/timex.h>
#include <syslog.h> #include <syslog.h>
#include <stdarg.h> #include <stdarg.h>
#include <limits.h> #include <limits.h>
#include <pwd.h> #include <pwd.h>
#include <grp.h> #include <grp.h>
#include <float.h>
#if defined __NetBSD__ || defined __FreeBSD__ || defined __APPLE__ #if defined __NetBSD__ || defined __FreeBSD__ || defined __APPLE__
#define adjtimex ntp_adjtime #define adjtimex ntp_adjtime
#endif #endif
#ifdef ENABLE_HTTPS #ifdef ENABLE_HTTPS
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif #endif
#define VERSION "1.3.3" #define VERSION "1.3.4"
#define MAX_HTTP_HOSTS 16 /* 16 web servers */ #define MAX_HTTP_HOSTS 16 /* 16 web servers */
#define DEFAULT_HTTP_PORT "80" #define DEFAULT_HTTP_PORT "80"
#define DEFAULT_PROXY_PORT "8080" #define DEFAULT_PROXY_PORT "8080"
#define DEFAULT_IP_VERSION PF_UNSPEC /* IPv6 and IPv4 */ #define DEFAULT_IP_VERSION PF_UNSPEC /* IPv6 and IPv4 */
#define DEFAULT_HTTP_VERSION "1" /* HTTP/1.1 */ #define DEFAULT_HTTP_VERSION "1" /* HTTP/1.1 */
#define DEFAULT_TIME_LIMIT 31536000 /* 1 year */ #define DEFAULT_TIME_LIMIT 31536000 /* 1 year */
#define NO_TIME_LIMIT -1 #define NO_TIME_LIMIT -1
#define ERR_TIMESTAMP LONG_MAX /* Err fetching date in getHT TPdate */ #define ERR_TIMESTAMP DBL_MAX /* Err fetching date in getHTT Pdate */
#define DEFAULT_PRECISION 4 /* 4 request per host */ #define DEFAULT_PRECISION 4 /* 4 request per host */
#define DEFAULT_MIN_SLEEP 1800 /* 30 minutes */ #define DEFAULT_MIN_SLEEP 1800 /* 30 minutes */
#define DEFAULT_MAX_SLEEP 115200 /* 32 hours */ #define DEFAULT_MAX_SLEEP 115200 /* 32 hours */
#define MAX_DRIFT 32768000 /* 500 PPM */ #define MAX_DRIFT 32768000 /* 500 PPM */
#define DEFAULT_PID_FILE "/var/run/htpdate.pid" #define DEFAULT_PID_FILE "/var/run/htpdate.pid"
#define HEADREQUESTSIZE 1024 #define HEADREQUESTSIZE 1024
#define URLSIZE 128 #define URLSIZE 128
#define BUFFERSIZE 8192 #define BUFFERSIZE 8192
#define PRINTBUFFERSIZE BUFFERSIZE #define PRINTBUFFERSIZE BUFFERSIZE
#define sign(x) (x < 0 ? (-1) : 1) #define sign(x) (x < 0 ? (-1) : 1)
/* By default turn off "debug" and "log" mode */ /* By default turn off "debug" and "log" mode */
static int debug = 0; static int debug = 0;
static int logmode = 0; static int logmode = 0;
static int verifycert = 0; static int verifycert = 0;
/* Insertion sort is more efficient (and smaller) than qsort for small lists */ /* Insertion sort is more efficient (and smaller) than qsort for small lists */
static void insertsort(double a[], long length) { static void insertsort(double a[], int length) {
long i, j; long i, j;
for (i = 1; i < length; i++) { for (i = 1; i < length; i++) {
double value = a[i]; double value = a[i];
for (j = i - 1; j >= 0 && a[j] > value; j--) for (j = i - 1; j >= 0 && a[j] > value; j--)
a[j+1] = a[j]; a[j+1] = a[j];
a[j+1] = value; a[j+1] = value;
} }
} }
skipping to change at line 188 skipping to change at line 189
} }
} }
static void swgid(int id) { static void swgid(int id) {
if (setegid(id)) { if (setegid(id)) {
printlog(1, "setegid() %i", id); printlog(1, "setegid() %i", id);
exit(1); exit(1);
} }
} }
static long getoffset(char remote_time[25]) { static long long getoffset(char remote_time[25]) {
struct timeval timevalue = {LONG_MAX, 0}; struct timeval timevalue = {0, 0};
struct timespec now; struct timespec now;
struct tm tm; struct tm tm;
clock_gettime(CLOCK_REALTIME, &now); clock_gettime(CLOCK_REALTIME, &now);
memset(&tm, 0, sizeof(struct tm)); memset(&tm, 0, sizeof(struct tm));
if (strptime(remote_time, "%d %b %Y %T", &tm) != NULL) { if (strptime(remote_time, "%d %b %Y %T", &tm) != NULL) {
timevalue.tv_sec = timegm(&tm); timevalue.tv_sec = timegm(&tm);
} else { } else {
printlog(1, "unknown time format"); printlog(1, "unknown time format");
} }
skipping to change at line 298 skipping to change at line 299
if (proxy == NULL) { if (proxy == NULL) {
rc = getaddrinfo(host, port, &hints, &res); rc = getaddrinfo(host, port, &hints, &res);
} else { } else {
snprintf(url, URLSIZE, "http://%s:%s", host, port); snprintf(url, URLSIZE, "http://%s:%s", host, port);
rc = getaddrinfo(proxy, proxyport, &hints, &res); rc = getaddrinfo(proxy, proxyport, &hints, &res);
} }
/* Was the hostname and service resolvable? */ /* Was the hostname and service resolvable? */
if (rc) { if (rc) {
printlog(1, "%s host or service unavailable", host); printlog(1, "%s host or service unavailable", host);
return(0); /* Assume correct time */ return(ERR_TIMESTAMP);
} }
/* Build a combined HTTP/1.0 and 1.1 HEAD request /* Build a combined HTTP/1.0 and 1.1 HEAD request
Pragma: no-cache, "forces" an HTTP/1.0 and 1.1 compliant Pragma: no-cache, "forces" an HTTP/1.0 and 1.1 compliant
web server to return a fresh timestamp web server to return a fresh timestamp
Connection: keep-alive, for multiple requests Connection: keep-alive, for multiple requests
*/ */
snprintf(headrequest, HEADREQUESTSIZE, snprintf(headrequest, HEADREQUESTSIZE,
"HEAD %s/%s HTTP/1.%s\r\n" "HEAD %s/%s HTTP/1.%s\r\n"
"Host: %s\r\n" "Host: %s\r\n"
skipping to change at line 336 skipping to change at line 337
continue; continue;
} }
break; break;
} while ((res = res->ai_next)); } while ((res = res->ai_next));
freeaddrinfo(res); freeaddrinfo(res);
if (rc) { if (rc) {
printlog(1, "%s connection failed", host); printlog(1, "%s connection failed", host);
return((double)ERR_TIMESTAMP); return(ERR_TIMESTAMP);
} }
#ifdef ENABLE_HTTPS #ifdef ENABLE_HTTPS
SSL_CTX *tls_ctx = SSL_CTX_new(TLS_method()); SSL_CTX *tls_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_default_verify_paths(tls_ctx); SSL_CTX_set_default_verify_paths(tls_ctx);
SSL_CTX_set_verify_depth(tls_ctx, 4); SSL_CTX_set_verify_depth(tls_ctx, 4);
if (verifycert) SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_PEER, NULL); if (verifycert) SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_PEER, NULL);
SSL *conn = SSL_new(tls_ctx); SSL *conn = SSL_new(tls_ctx);
if (scheme) { if (scheme) {
if (proxy) { if (proxy) {
rc = proxyCONNECT(server_s, host, port, proxy, proxyport, httpversio n); rc = proxyCONNECT(server_s, host, port, proxy, proxyport, httpversio n);
if (rc != 1) { if (rc != 1) {
printlog(1, "Proxy error: %i", rc); printlog(1, "Proxy error: %i", rc);
return(ERR_TIMESTAMP);
} }
} }
rc = SSL_set_fd(conn, server_s); if (! SSL_set_fd(conn, server_s)) {
if (rc != 1) { printlog(1, "TLS error1");
printlog(1, "SSL error1: %i", rc); return(ERR_TIMESTAMP);
rc = -1;
} else { } else {
rc = SSL_connect(conn); if (SSL_connect(conn) != 1) {
if (rc != 1) { printlog(1, "TLS error2");
printlog(1, "SSL error2: %i", rc); return(ERR_TIMESTAMP);
rc = -1;
} }
} }
} }
#endif #endif
long offset = 0; long long offset = 0, first_offset = 0, prev_offset = 0;
long first_offset = 0;
long prev_offset = 0;
long nap = 1e9L; long nap = 1e9L;
long when = nap >> precision; long when = nap >> precision;
do { do {
if (debug > 1) if (debug > 1)
printlog(0, "bisect: %i, when: %09li", polls, when); printlog(0, "bisect: %i, when: %09li", polls, when);
/* Initialize timer */ /* Initialize timer */
clock_gettime(CLOCK_REALTIME, &now); clock_gettime(CLOCK_REALTIME, &now);
/* Initialize RTT (start of measurement) */ /* Initialize RTT (start of measurement) */
skipping to change at line 431 skipping to change at line 429
} else { } else {
first_offset=offset; first_offset=offset;
} }
prev_offset=offset; prev_offset=offset;
/* Print host, raw timestamp, round trip time */ /* Print host, raw timestamp, round trip time */
if (debug) if (debug)
printlog(0, "%-25s %s, %s (%li ms) => %li", host, port, printlog(0, "%-25s %s, %s (%li ms) => %li", host, port,
remote_time, rtt / (long)1e6, offset); remote_time, rtt / (long)1e6, offset);
} else { } else {
printlog(1, "%s no timestamp", host); printlog(1, "%s no timestamp", host);
return(ERR_TIMESTAMP);
} }
} /* bytes received */ } /* bytes received */
precision--; precision--;
when += nap; when += nap;
} while (precision >= 1); } while (precision >= 1);
close(server_s); close(server_s);
#ifdef ENABLE_HTTPS #ifdef ENABLE_HTTPS
if (scheme) SSL_shutdown(conn); if (scheme) SSL_shutdown(conn);
SSL_CTX_free(tls_ctx); SSL_CTX_free(tls_ctx);
SSL_free(conn); SSL_free(conn);
#endif #endif
/* Rounding */ /* Rounding */
if (debug) printlog(0, "when: %ld, nap: %ld", when, nap); if (debug) printlog(0, "when: %ld, nap: %ld", when, nap);
if (when + nap == 1e9 && offset == 0) return 0; if (when + nap == 1e9 && offset == 0) return 0;
if (offset < 0) when -= nap;
/* Return the time delta between web server time (timevalue) /* Return the time delta between web server time (timevalue)
and system time (now) and system time (now)
*/ */
if (first_offset < 0) { if (first_offset < 0) {
return(-first_offset + (1e9L-when)/(double)1e9L); return(-first_offset + (1e9L-when)/(double)1e9L);
} else { } else {
return(-first_offset + 1 - when/(double)1e9L); return(-first_offset + 1 - when/(double)1e9L);
} }
} }
skipping to change at line 511 skipping to change at line 509
} }
} }
static int init_frequency(char *driftfile) { static int init_frequency(char *driftfile) {
struct timex tmx; struct timex tmx;
FILE *fp; FILE *fp;
fp = fopen(driftfile, "r"); fp = fopen(driftfile, "r");
if (fp != NULL) { if (fp != NULL) {
if (fscanf(fp, "%li", &tmx.freq)) { if (fscanf(fp, "%li", &tmx.freq)) {
printlog(0, "Reading frequency from file %li", tmx.freq); printlog(0, "Reading frequency from file %li", tmx.freq);
fclose(fp);
} else { } else {
printlog(1, "Error reading frequency from %s", driftfile); printlog(1, "Error reading frequency from %s", driftfile);
fclose(fp);
return -1;
} }
fclose(fp);
return -1;
} else { } else {
printlog(1, "Error reading frequency from %s", driftfile); printlog(1, "Error reading frequency from %s", driftfile);
return -1; return -1;
} }
if ((tmx.freq < -MAX_DRIFT) || (tmx.freq > MAX_DRIFT)) if ((tmx.freq < -MAX_DRIFT) || (tmx.freq > MAX_DRIFT))
tmx.freq = sign(tmx.freq) * MAX_DRIFT; tmx.freq = sign(tmx.freq) * MAX_DRIFT;
printlog(0, "Set frequency: %li", tmx.freq); printlog(0, "Set frequency: %li", tmx.freq);
tmx.modes = MOD_FREQUENCY; tmx.modes = MOD_FREQUENCY;
/* Become root */ /* Become root */
swuid(0); swuid(0);
skipping to change at line 665 skipping to change at line 664
fprintf(pid_file, "%d\n", pid); fprintf(pid_file, "%d\n", pid);
fclose(pid_file); fclose(pid_file);
} }
exit(0); exit(0);
} }
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char *host = NULL, *proxy = NULL, *proxyport = NULL; char *host = NULL, *proxy = NULL, *proxyport = NULL;
char *port = NULL; char *port = NULL;
char *hostport = NULL;
char *path = NULL; char *path = NULL;
char *scheme = NULL; char *scheme = NULL;
char *httpversion = DEFAULT_HTTP_VERSION; char *httpversion = DEFAULT_HTTP_VERSION;
char *pidfile = DEFAULT_PID_FILE; char *pidfile = DEFAULT_PID_FILE;
char *user = NULL, *userstr = NULL, *group = NULL; char *user = NULL, *userstr = NULL, *group = NULL;
double timeavg, drift = 0; double timeavg, drift = 0;
double timedelta[MAX_HTTP_HOSTS-1]; double timedelta[MAX_HTTP_HOSTS-1];
long numservers; int numservers;
long precision = DEFAULT_PRECISION; int precision = DEFAULT_PRECISION;
int setmode = 0; int setmode = 0;
int i, param; int i, param;
int daemonize = 0, foreground = 0; int daemonize = 0, foreground = 0;
int noproxyenv = 0; int noproxyenv = 0;
int ipversion = DEFAULT_IP_VERSION; int ipversion = DEFAULT_IP_VERSION;
long timelimit = DEFAULT_TIME_LIMIT; long long timelimit = DEFAULT_TIME_LIMIT;
int minsleep = DEFAULT_MIN_SLEEP; int minsleep = DEFAULT_MIN_SLEEP;
int maxsleep = DEFAULT_MAX_SLEEP; int maxsleep = DEFAULT_MAX_SLEEP;
int sleeptime = minsleep; int sleeptime = minsleep;
int sw_uid = 0, sw_gid = 0; int sw_uid = 0, sw_gid = 0;
time_t starttime = 0; time_t starttime = 0;
struct passwd *pw; struct passwd *pw;
struct group *gr; struct group *gr;
extern char *optarg; extern char *optarg;
skipping to change at line 862 skipping to change at line 860
#ifdef ENABLE_HTTPS #ifdef ENABLE_HTTPS
SSL_library_init(); SSL_library_init();
#endif #endif
/* Infinite poll cycle loop in daemonize or foreground mode */ /* Infinite poll cycle loop in daemonize or foreground mode */
do { do {
/* Initialize number of received valid timestamps, good timestamps /* Initialize number of received valid timestamps, good timestamps
and the average of the good timestamps and the average of the good timestamps
*/ */
long validtimes = 0, goodtimes = 0; int validtimes = 0, goodtimes = 0;
double sumtimes = 0, mean = 0; double sumtimes = 0, mean = 0;
/* Loop through the time sources (web servers); poll cycle */ /* Loop through the time sources (web servers); poll cycle */
for (i = optind; i < argc; i++) { for (i = optind; i < argc; i++) {
/* host:port is stored in argv[i] */ /* host:port is stored in argv[i] */
hostport = (char *)argv[i]; char *hostport = strdup(argv[i]);
host = strdup(hostport); host = hostport;
splitURL(&scheme, &host, &port, &path); splitURL(&scheme, &host, &port, &path);
double offset = getHTTPdate(scheme, host, port, path, double offset = getHTTPdate(scheme, host, port, path,
proxy, proxyport, httpversion, ipversion, precision); proxy, proxyport, httpversion, ipversion, precision);
if (debug) printlog(0, "offset: %.6f", offset); free(hostport);
if (debug && offset != ERR_TIMESTAMP) {
printlog(0, "offset: %.6f", offset);
}
/* Only include valid responses in timedelta[] */ /* Only include valid responses in timedelta[] */
if (timelimit == NO_TIME_LIMIT || (offset < timelimit && offset > -t imelimit)) { if ((timelimit == NO_TIME_LIMIT && offset != ERR_TIMESTAMP) || (offs et < timelimit && offset > -timelimit)) {
timedelta[validtimes] = offset; timedelta[validtimes] = offset;
validtimes++; validtimes++;
} }
/* Sleep for a while, unless a time offset is detected */
if ((daemonize || foreground) && !offset)
sleep(sleeptime / numservers);
} }
/* Sort the timedelta results */ /* Sort the timedelta results */
insertsort(timedelta, validtimes); insertsort(timedelta, validtimes);
/* Mean time value */ /* Mean time value */
mean = timedelta[validtimes/2]; mean = timedelta[validtimes/2];
/* Filter out the bogus timevalues. A timedelta which is more than /* Filter out the bogus timevalues. A timedelta which is more than
1 second off from mean, is considered a 'false ticker'. 1 second off from mean, is considered a 'false ticker'.
skipping to change at line 951 skipping to change at line 948
/* Decrease polling interval to minimum */ /* Decrease polling interval to minimum */
sleeptime = minsleep; sleeptime = minsleep;
/* Sleep for 30 minutes after a time adjust or set */ /* Sleep for 30 minutes after a time adjust or set */
sleep(DEFAULT_MIN_SLEEP); sleep(DEFAULT_MIN_SLEEP);
} }
} else { } else {
/* Increase polling interval */ /* Increase polling interval */
if (sleeptime < maxsleep) sleeptime <<= 1; if (sleeptime < maxsleep) sleeptime <<= 1;
} }
if (daemonize || foreground)
printlog(0, "poll: %ld s", sleeptime);
} else { if (daemonize || foreground) {
printlog(1, "No server suitable for synchronization found"); printlog(0, "sleep for %ld s", sleeptime);
/* Sleep for minsleep to avoid flooding */ sleep(sleeptime);
if (daemonize || foreground)
sleep(minsleep);
else
exit(1);
} }
/* After first poll cycle do not step through time, only adjust */ } else {
if (setmode != 3) setmode = 1; printlog(1, "No server suitable for synchronization found");
/* Sleep for minsleep to avoid flooding */
if (daemonize || foreground)
sleep(minsleep);
else
exit(1);
}
/* After first poll cycle do not step through time, only adjust */
if (setmode != 3) setmode = 1;
} while (daemonize || foreground); /* end of infinite while loop */ } while (daemonize || foreground); /* end of infinite while loop */
exit(0); exit(0);
} }
 End of changes. 29 change blocks. 
48 lines changed or deleted 48 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)