1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*************************************************************************** 29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * _ _ ____ _ 39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Project ___| | | | _ \| | 49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * / __| | | | |_) | | 59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | (__| |_| | _ <| |___ 69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * \___|\___/|_| \_\_____| 79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 88f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 99bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which 11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms 128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is 16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file. 17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied. 20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/ 228f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo/* <DESC> 238f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * Set your system time from a remote HTTP server's Date: header. 248f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * </DESC> 258f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo */ 26e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* This example code only builds as-is on Windows. 279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * While Unix/Linux user, you do not need this software. 299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * You can achieve the same result as synctime using curl, awk and date. 309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Set proxy as according to your network, but beware of proxy Cache-Control. 319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * To set your system clock, root access is required. 339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * # date -s "`curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \ 349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | awk -F': ' '/Date: / {print $2}'`" 359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * To view remote webserver date and time. 379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * $ curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \ 389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | awk -F': ' '/Date: / {print $2}' 399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Synchronising your computer clock via Internet time server usually relies 419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * on DAYTIME, TIME, or NTP protocols. These protocols provide good accurate 429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * time synchronisation but it does not work very well through a 439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * firewall/proxy. Some adjustment has to be made to the firewall/proxy for 449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * these protocols to work properly. 459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * There is an indirect method. Since most webserver provide server time in 479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * their HTTP header, therefore you could synchronise your computer clock 489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * using HTTP protocol which has no problem with firewall/proxy. 499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * For this software to work, you should take note of these items. 519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 1. Your firewall/proxy must allow your computer to surf internet. 529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2. Webserver system time must in sync with the NTP time server, 539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * or at least provide an accurate time keeping. 549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 3. Webserver HTTP header does not provide the milliseconds units, 559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * so there is no way to get very accurate time. 569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 4. This software could only provide an accuracy of +- a few seconds, 579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * as Round-Trip delay time is not taken into consideration. 589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Compensation of network, firewall/proxy delay cannot be simply divide 599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * the Round-Trip delay time by half. 609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 5. Win32 SetSystemTime() API will set your computer clock according to 619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GMT/UTC time. Therefore your computer timezone must be properly set. 629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 6. Webserver data should not be cached by the proxy server. Some 639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * webserver provide Cache-Control to prevent caching. 649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * References: 669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * http://tf.nist.gov/timefreq/service/its.htm 679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * http://tf.nist.gov/timefreq/service/firewall.htm 689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Usage: 709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This software will synchronise your computer clock only when you issue 719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * it with --synctime. By default, it only display the webserver's clock. 729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Written by: Frank (contributed to libcurl) 749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * IN NO EVENT SHALL THE AUTHOR OF THIS SOFTWARE BE LIABLE FOR 809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * OF THIS SOFTWARE. 859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <stdio.h> 899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <time.h> 909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#ifndef __CYGWIN__ 919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <windows.h> 929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <curl/curl.h> 949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define MAX_STRING 256 979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define MAX_STRING1 MAX_STRING+1 989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define SYNCTIME_UA "synctime/1.0" 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelstypedef struct 1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char http_proxy[MAX_STRING1]; 1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char proxy_user[MAX_STRING1]; 1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char timeserver[MAX_STRING1]; 1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} conf_t; 1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETconst char DefaultTimeServer[3][MAX_STRING1] = 1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "http://pool.ntp.org/", 111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "http://nist.time.gov/", 112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "http://www.google.com/" 1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst char *DayStr[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst char *MthStr[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint ShowAllHeader; 1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint AutoSyncTime; 1219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsSYSTEMTIME SYSTime; 1229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsSYSTEMTIME LOCALTime; 1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define HTTP_COMMAND_HEAD 0 1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define HTTP_COMMAND_GET 1 1269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelssize_t SyncTime_CURL_WriteOutput(void *ptr, size_t size, size_t nmemb, 1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels void *stream) 1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fwrite(ptr, size, nmemb, stream); 1328f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo return (nmemb*size); 1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelssize_t SyncTime_CURL_WriteHeader(void *ptr, size_t size, size_t nmemb, 1369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels void *stream) 1379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int i, RetVal; 1399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char TmpStr1[26], TmpStr2[26]; 1409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1418f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(ShowAllHeader == 1) 1429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "%s", (char *)(ptr)); 1439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1448f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strncmp((char *)(ptr), "Date:", 5) == 0) { 1458f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(ShowAllHeader == 0) 1469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "HTTP Server. %s", (char *)(ptr)); 1479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1488f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(AutoSyncTime == 1) { 1499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *TmpStr1 = 0; 1509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *TmpStr2 = 0; 1518f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strlen((char *)(ptr)) > 50) /* Can prevent buffer overflow to 1529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels TmpStr1 & 2? */ 1539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels AutoSyncTime = 0; 1549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else { 155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET RetVal = sscanf ((char *)(ptr), "Date: %s %hu %s %hu %hu:%hu:%hu", 1569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels TmpStr1, &SYSTime.wDay, TmpStr2, &SYSTime.wYear, 1579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels &SYSTime.wHour, &SYSTime.wMinute, &SYSTime.wSecond); 1589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1598f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(RetVal == 7) { 1609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels SYSTime.wMilliseconds = 500; /* adjust to midpoint, 0.5 sec */ 1618f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo for(i=0; i<12; i++) { 1628f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strcmp(MthStr[i], TmpStr2) == 0) { 1639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels SYSTime.wMonth = i+1; 1649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 1659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels AutoSyncTime = 3; /* Computer clock will be adjusted */ 1689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else { 1709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels AutoSyncTime = 0; /* Error in sscanf() fields conversion */ 1719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1768f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strncmp((char *)(ptr), "X-Cache: HIT", 12) == 0) { 1779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "ERROR: HTTP Server data is cached." 1789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels " Server Date is no longer valid.\n"); 1799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels AutoSyncTime = 0; 1809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1818f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo return (nmemb*size); 1829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsvoid SyncTime_CURL_Init(CURL *curl, char *proxy_port, 1859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *proxy_user_password) 1869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1878f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strlen(proxy_port) > 0) 1889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_PROXY, proxy_port); 1899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1908f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strlen(proxy_user_password) > 0) 1919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_user_password); 1929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 193e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef SYNCTIME_UA 194e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(curl, CURLOPT_USERAGENT, SYNCTIME_UA); 195e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 1969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, *SyncTime_CURL_WriteOutput); 1979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, *SyncTime_CURL_WriteHeader); 1989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint SyncTime_CURL_Fetch(CURL *curl, char *URL_Str, char *OutFileName, 2019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int HttpGetBody) 2029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels FILE *outfile; 2049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLcode res; 2059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels outfile = NULL; 2078f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(HttpGetBody == HTTP_COMMAND_HEAD) 2089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); 2099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else { 2109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels outfile = fopen(OutFileName, "wb"); 2119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); 2129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(curl, CURLOPT_URL, URL_Str); 2159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels res = curl_easy_perform(curl); 2168f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(outfile != NULL) 2179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fclose(outfile); 2189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return res; /* (CURLE_OK) */ 2199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsvoid showUsage(void) 2229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "SYNCTIME: Synchronising computer clock with time server" 2249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels " using HTTP protocol.\n"); 2259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "Usage : SYNCTIME [Option]\n"); 2269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "Options :\n"); 2279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, " --server=WEBSERVER Use this time server instead" 2289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels " of default.\n"); 2299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, " --showall Show all HTTP header.\n"); 2309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, " --synctime Synchronising computer clock" 2319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels " with time server.\n"); 2329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, " --proxy-user=USER[:PASS] Set proxy username and" 2339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels " password.\n"); 2349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, " --proxy=HOST[:PORT] Use HTTP proxy on given" 2359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels " port.\n"); 2369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, " --help Print this help.\n"); 2379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "\n"); 2389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return; 2399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint conf_init(conf_t *conf) 2429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int i; 2449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *conf->http_proxy = 0; 2468f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo for(i=0; i<MAX_STRING1; i++) 2479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conf->proxy_user[i] = 0; /* Clean up password from memory */ 2489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *conf->timeserver = 0; 2499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 1; 2509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint main(int argc, char *argv[]) 2539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURL *curl; 2559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conf_t conf[1]; 2569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int OptionIndex; 2579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct tm *lt; 2589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct tm *gmt; 2599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels time_t tt; 2609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels time_t tt_local; 2619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels time_t tt_gmt; 2629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels double tzonediffFloat; 2639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int tzonediffWord; 2649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char timeBuf[61]; 2659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char tzoneBuf[16]; 2669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int RetValue; 2679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels OptionIndex = 0; 2699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ShowAllHeader = 0; /* Do not show HTTP Header */ 2709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels AutoSyncTime = 0; /* Do not synchronise computer clock */ 2719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RetValue = 0; /* Successful Exit */ 2729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conf_init(conf); 2739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2748f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(argc > 1) { 2758f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo while(OptionIndex < argc) { 2768f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strncmp(argv[OptionIndex], "--server=", 9) == 0) 2779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(conf->timeserver, MAX_STRING, "%s", &argv[OptionIndex][9]); 2789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2798f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strcmp(argv[OptionIndex], "--showall") == 0) 2809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ShowAllHeader = 1; 2819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2828f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strcmp(argv[OptionIndex], "--synctime") == 0) 2839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels AutoSyncTime = 1; 2849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2858f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strncmp(argv[OptionIndex], "--proxy-user=", 13) == 0) 2869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(conf->proxy_user, MAX_STRING, "%s", &argv[OptionIndex][13]); 2879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2888f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(strncmp(argv[OptionIndex], "--proxy=", 8) == 0) 2899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(conf->http_proxy, MAX_STRING, "%s", &argv[OptionIndex][8]); 2909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2918f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if((strcmp(argv[OptionIndex], "--help") == 0) || 2929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (strcmp(argv[OptionIndex], "/?") == 0)) { 2939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels showUsage(); 2949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 0; 2959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels OptionIndex++; 2979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3008f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(*conf->timeserver == 0) /* Use default server for time information */ 3019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(conf->timeserver, MAX_STRING, "%s", DefaultTimeServer[0]); 3029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Init CURL before usage */ 3049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_global_init(CURL_GLOBAL_ALL); 3059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl = curl_easy_init(); 3068f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(curl) { 3079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels SyncTime_CURL_Init(curl, conf->http_proxy, conf->proxy_user); 3089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Calculating time diff between GMT and localtime */ 3109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels tt = time(0); 3119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels lt = localtime(&tt); 3129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels tt_local = mktime(lt); 3139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels gmt = gmtime(&tt); 3149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels tt_gmt = mktime(gmt); 3159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels tzonediffFloat = difftime(tt_local, tt_gmt); 3169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels tzonediffWord = (int)(tzonediffFloat/3600.0); 3179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3188f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if((double)(tzonediffWord * 3600) == tzonediffFloat) 3199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(tzoneBuf, 15, "%+03d'00'", tzonediffWord); 3209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else 3219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(tzoneBuf, 15, "%+03d'30'", tzonediffWord); 3229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Get current system time and local time */ 3249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GetSystemTime(&SYSTime); 3259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GetLocalTime(&LOCALTime); 3269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ", 3279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay, 3289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels MthStr[LOCALTime.wMonth-1], LOCALTime.wYear, 3299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond, 3309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels LOCALTime.wMilliseconds); 3319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "Fetch: %s\n\n", conf->timeserver); 3339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "Before HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf); 3349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* HTTP HEAD command to the Webserver */ 3369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels SyncTime_CURL_Fetch(curl, conf->timeserver, "index.htm", 3379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels HTTP_COMMAND_HEAD); 3389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GetLocalTime(&LOCALTime); 3409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ", 3419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay, 3429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels MthStr[LOCALTime.wMonth-1], LOCALTime.wYear, 3439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond, 3449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels LOCALTime.wMilliseconds); 3459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "\nAfter HTTP. Date: %s%s\n", timeBuf, tzoneBuf); 3469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3478f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(AutoSyncTime == 3) { 3489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Synchronising computer clock */ 3498f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo if(!SetSystemTime(&SYSTime)) { /* Set system time */ 3509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "ERROR: Unable to set system time.\n"); 3519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RetValue = 1; 3529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else { 3549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Successfully re-adjusted computer clock */ 3559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GetLocalTime(&LOCALTime); 3569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ", 3579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay, 3589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels MthStr[LOCALTime.wMonth-1], LOCALTime.wYear, 3599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond, 3609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels LOCALTime.wMilliseconds); 3619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(stderr, "\nNew System's Date: %s%s\n", timeBuf, tzoneBuf); 3629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Cleanup before exit */ 3669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conf_init(conf); 3679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_cleanup(curl); 3689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return RetValue; 3709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 371