|
@@ -1,199 +0,0 @@
|
|
|
---- htpdate.c 2012-08-29 11:17:21.000000000 +0000
|
|
|
-+++ htpdate.c 2012-08-29 11:43:03.000000000 +0000
|
|
|
-@@ -30,6 +30,18 @@
|
|
|
- http://www.gnu.org/copyleft/gpl.html
|
|
|
- */
|
|
|
-
|
|
|
-+/*
|
|
|
-+ Modifications by mk@dee.su:
|
|
|
-+
|
|
|
-+ + Set the time once able to do so, even if not in first poll cycle
|
|
|
-+ + Ignore error responses (usually by proxies)
|
|
|
-+ + Better error handling during communication
|
|
|
-+ + Buffer overflow prevention when copying Date: header contents
|
|
|
-+ + Added -T <tagfile> option to specify output file with initial time step
|
|
|
-+ + Fixed umask setting
|
|
|
-+ + Fixed group privileges dropping
|
|
|
-+ */
|
|
|
-+
|
|
|
- /* Needed to avoid implicit warnings from strptime */
|
|
|
- #define _GNU_SOURCE
|
|
|
-
|
|
|
-@@ -144,6 +156,7 @@
|
|
|
- static long getHTTPdate( char *host, char *port, char *proxy, char *proxyport, char *httpversion, int ipversion, int when ) {
|
|
|
- int server_s;
|
|
|
- int rc;
|
|
|
-+ int success = 0;
|
|
|
- struct addrinfo hints, *res, *res0;
|
|
|
- struct tm tm;
|
|
|
- struct timeval timevalue = {LONG_MAX, 0};
|
|
|
-@@ -240,7 +253,8 @@
|
|
|
- /* Receive data from the web server
|
|
|
- The return code from recv() is the number of bytes received
|
|
|
- */
|
|
|
-- if ( recv(server_s, buffer, BUFFERSIZE, 0) != -1 ) {
|
|
|
-+ buffer[BUFFERSIZE-1] = '\0';
|
|
|
-+ if ( recv(server_s, buffer, BUFFERSIZE-1, 0) != -1 ) {
|
|
|
-
|
|
|
- /* Assuming that network delay (server->htpdate) is neglectable,
|
|
|
- the received web server time "should" match the local time.
|
|
|
-@@ -261,13 +275,16 @@
|
|
|
- timeofday.tv_usec - when;
|
|
|
-
|
|
|
- /* Look for the line that contains Date: */
|
|
|
-- if ( (pdate = strstr(buffer, "Date: ")) != NULL ) {
|
|
|
-- strncpy(remote_time, pdate + 11, 24);
|
|
|
-+ if ( strncmp(buffer, "HTTP/1.1 2", 10) != 0 && strncmp(buffer, "HTTP/1.1 3", 10) != 0 ) {
|
|
|
-+ printlog( 1, "Ignoring error/proxy response" );
|
|
|
-+ } else if ( (pdate = strstr(buffer, "\nDate: ")) != NULL && buffer+BUFFERSIZE - pdate > 12 + 24 ) {
|
|
|
-+ strncpy(remote_time, pdate + 12, 24);
|
|
|
-
|
|
|
- if ( strptime( remote_time, "%d %b %Y %T", &tm) != NULL) {
|
|
|
- /* Web server timestamps are without daylight saving */
|
|
|
- tm.tm_isdst = 0;
|
|
|
- timevalue.tv_sec = mktime(&tm);
|
|
|
-+ success = 1;
|
|
|
- } else {
|
|
|
- printlog( 1, "%s unknown time format", host );
|
|
|
- }
|
|
|
-@@ -289,7 +306,7 @@
|
|
|
- /* Return the time delta between web server time (timevalue)
|
|
|
- and system time (timeofday)
|
|
|
- */
|
|
|
-- return( timevalue.tv_sec - timeofday.tv_sec + gmtoffset );
|
|
|
-+ return success ? ( timevalue.tv_sec - timeofday.tv_sec + gmtoffset ) : LONG_MAX;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-@@ -387,7 +404,7 @@
|
|
|
- puts("htpdate version "VERSION"\n\
|
|
|
- Usage: htpdate [-046abdhlqstxD] [-i pid file] [-m minpoll] [-M maxpoll]\n\
|
|
|
- [-p precision] [-P <proxyserver>[:port]] [-u user[:group]]\n\
|
|
|
-- <host[:port]> ...\n\n\
|
|
|
-+ [-T <timeshiftfile>] <host[:port]> ...\n\n\
|
|
|
- -0 HTTP/1.0 request\n\
|
|
|
- -4 Force IPv4 name resolution only\n\
|
|
|
- -6 Force IPv6 name resolution only\n\
|
|
|
-@@ -405,6 +422,7 @@
|
|
|
- -q query only, don't make time changes (default)\n\
|
|
|
- -s set time\n\
|
|
|
- -t turn off sanity time check\n\
|
|
|
-+ -T output time delta after initial shift with -s\n\
|
|
|
- -u run daemon as user\n\
|
|
|
- -x adjust kernel clock\n\
|
|
|
- host web server hostname or ip address (maximum of 16)\n\
|
|
|
-@@ -448,7 +466,7 @@
|
|
|
- signal(SIGHUP, SIG_IGN);
|
|
|
-
|
|
|
- /* Change the file mode mask */
|
|
|
-- umask(0);
|
|
|
-+ umask(022);
|
|
|
-
|
|
|
- /* Change the current working directory */
|
|
|
- if ( chdir("/") < 0 ) {
|
|
|
-@@ -480,8 +498,25 @@
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-+static void writetagfile( char *tagfile, double timedelta ) {
|
|
|
-+ FILE *file = fopen ( tagfile, "w" );
|
|
|
-+
|
|
|
-+ if ( !file )
|
|
|
-+ printlog (1, "could not create %s", tagfile);
|
|
|
-+
|
|
|
-+ else {
|
|
|
-+ if ( fprintf( file, "%.3f\n", timedelta ) < 0 )
|
|
|
-+ printlog (1, "could not write time delta to %s", tagfile);
|
|
|
-+
|
|
|
-+ if ( fclose( file ) )
|
|
|
-+ printlog (1, "could not successfully close %s", tagfile);
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+
|
|
|
- int main( int argc, char *argv[] ) {
|
|
|
- char *host = NULL, *proxy = NULL, *proxyport = NULL;
|
|
|
-+ char *tagfile = NULL;
|
|
|
- char *port;
|
|
|
- char *httpversion = DEFAULT_HTTP_VERSION;
|
|
|
- char *pidfile = DEFAULT_PID_FILE;
|
|
|
-@@ -500,6 +535,7 @@
|
|
|
- int maxsleep = DEFAULT_MAX_SLEEP;
|
|
|
- int sleeptime = minsleep;
|
|
|
- int sw_uid = 0, sw_gid = 0;
|
|
|
-+ int hassettime = 0;
|
|
|
- time_t starttime = 0;
|
|
|
-
|
|
|
- struct passwd *pw;
|
|
|
-@@ -510,7 +546,7 @@
|
|
|
-
|
|
|
-
|
|
|
- /* Parse the command line switches and arguments */
|
|
|
-- while ( (param = getopt(argc, argv, "046abdhi:lm:p:qstu:xDM:P:") ) != -1)
|
|
|
-+ while ( (param = getopt(argc, argv, "046abdhi:lm:p:qstu:xDM:P:T:") ) != -1)
|
|
|
- switch( param ) {
|
|
|
-
|
|
|
- case '0': /* HTTP/1.0 */
|
|
|
-@@ -604,6 +640,9 @@
|
|
|
- proxyport = DEFAULT_PROXY_PORT;
|
|
|
- splithostport( &proxy, &proxyport );
|
|
|
- break;
|
|
|
-+ case 'T':
|
|
|
-+ tagfile = (char *)optarg;
|
|
|
-+ break;
|
|
|
- case '?':
|
|
|
- return 1;
|
|
|
- default:
|
|
|
-@@ -638,8 +677,8 @@
|
|
|
- }
|
|
|
-
|
|
|
- /* Now we are root, we drop the privileges (if specified) */
|
|
|
-- if ( sw_uid ) seteuid( sw_uid );
|
|
|
- if ( sw_gid ) setegid( sw_gid );
|
|
|
-+ if ( sw_uid ) seteuid( sw_uid );
|
|
|
-
|
|
|
- /* Calculate GMT offset from local timezone */
|
|
|
- time(&gmtoffset);
|
|
|
-@@ -758,7 +797,7 @@
|
|
|
- }
|
|
|
-
|
|
|
- /* Do I really need to change the time? */
|
|
|
-- if ( sumtimes || !daemonize ) {
|
|
|
-+ if ( sumtimes || !daemonize || setmode == 2 ) {
|
|
|
- /* If a precision was specified and the time offset is small
|
|
|
- (< +-1 second), adjust the time with the value of precision
|
|
|
- */
|
|
|
-@@ -768,10 +807,21 @@
|
|
|
- /* Correct the clock, if not in "adjtimex" mode */
|
|
|
- if ( setclock( timeavg, setmode ) < 0 )
|
|
|
- printlog( 1, "Time change failed" );
|
|
|
-+ /* After first correction, do not step through time, only adjust */
|
|
|
-+ else if ( setmode == 2 ) {
|
|
|
-+ hassettime = 1;
|
|
|
-+ setmode = 1;
|
|
|
-+ }
|
|
|
-
|
|
|
- /* Drop root privileges again */
|
|
|
- if ( sw_uid ) seteuid( sw_uid );
|
|
|
-
|
|
|
-+ /* Create a tag file if requested */
|
|
|
-+ if ( tagfile && hassettime ) {
|
|
|
-+ writetagfile( tagfile, timeavg );
|
|
|
-+ tagfile = NULL;
|
|
|
-+ }
|
|
|
-+
|
|
|
- if ( daemonize ) {
|
|
|
- if ( starttime ) {
|
|
|
- /* Calculate systematic clock drift */
|
|
|
-@@ -814,11 +864,6 @@
|
|
|
- exit(1);
|
|
|
- }
|
|
|
-
|
|
|
-- /* After first poll cycle do not step through time, only adjust */
|
|
|
-- if ( setmode != 3 ) {
|
|
|
-- setmode = 1;
|
|
|
-- }
|
|
|
--
|
|
|
- } while ( daemonize ); /* end of infinite while loop */
|
|
|
-
|
|
|
- exit(0);
|