⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntptimeset.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * ntptimeset - get/set the time via ntp * * GOAL: * The goal of ntptime is to set the current time on system startup * to the best possible time using the network very wisely. It is assumed * that after a resonable time has been sett then ntp daemon will * maintain it. * * PROBLEM DOMAIN: * We have three sets of issues related to acheiving the goal. The first * issue is using the network when normal traffic is happening or when * the entire network world is recovering from a campus wide power failure * and is restarting. The second issue is the class of machine whether it * is a user's office workstation being handled by an uneducated user or * a server computer being handled by a trained operations staff. The third * issue is whether the ratio of people to computers and whether the  * environment is stable and viable or not. * * NETWORK USAGE: * The first issue of using the network wisely is a question of whether * the network load and time server load and state are normal. If things * are normal ntptime can do what ntpdate does of sending out 4 packets * quickly to each server (new transmit done with each ack). However * if network or time load is high then this scheme will simply contribute * to problems. Given we have minimal state, we simply weight lost packets * significantly and make sure we throttle output as much as possible * without performance lost for quick startups. * * TRAINING AND KNOWLEDGE: * The second issue of uneducated user of a office workstation versus a * trained operation staff of a server machine translates into simply an * issue of untrained and trained users. *  * The training issue implies that for the sake of the users involved in the * handling of their office workstation, problems and options should be * communicated simply and effectively and not in terse expert related * descriptions without possible options to be taken. The operator's training * and education enables them to deal with either type of communication and * control. * * AUTOMATION AND MANUAL CONTROL: * The last issue boils down to a design problem. If the design tends to go * into a manual mode when the environment is non-viable then one person * handling many computers all at the same time will be heavily impacted. On * the other hand, if the design tends to be automatic and does not indicate * a way for the user to take over control then the computer will be * unavailable for the user until the proble is resolved by someone else or * the user. * * NOTE: Please do not have this program print out every minute some line, *       of output. If this happens and the environment is in trouble then *       many pages of paper on many different machines will be filled up. *       Save some tress in your lifetime. *  * CONCLUSION: * The behavior of the program derived from these three issues should be * that during normal situations it quickly sets the time and allow the * system to startup. * * However during abnormal conditions as detected by unresponsive servers, * out-of-sync or bad responses and other detections, it should print out * a simple but clear message and continue in a mellow way to get the best * possible time. It may never get the time and if so should also indicate * this. * * Rudy Nedved * 18-May-1993 * **************************************************************** * * Much of the above is confusing or no longer relevant.  For example, * it is rare these days for a machine's console to be a printing terminal, * so the comment about saving trees doesn't mean much.  Nonetheless, * the basic principles still stand: * * - Work automatically, without human control or intervention.  To *   this end, we use the same configuration file as ntpd itself, so *   you don't have to specify servers or other information on the *   command line.  We also recognize that sometimes we won't be able *   to contact any servers, and give up in that event instead of *   hanging forever. * * - Behave in a sane way, both internally and externally, even in the *   face of insane conditions.  That means we back off quickly when *   we don't hear a response, to avoid network congestion.  Like *   ntpd, we verify responses from several servers before accepting *   the new time data. * *   However, we don't assume that the local clock is right, or even *   close, because it might not be at boot time, and we want to catch *   and correct that situation.  This behaviour has saved us in several *   instances.  On HP-UX 9.0x, there used to be a bug in adjtimed which *   would cause the time to be set to some wild value, making the machine *   essentially unusable (we use Kerberos authentication pervasively, *   and it requires workstations and servers to have a time within five *   minutes of the Kerberos server).  We also have problems on PC's *   running both Linux and some Microsoft OS -- they tend to disagree *   on what the BIOS clock should say, and who should update it, and *   when.  On those systems, we not only run ntptimeset at boot, we *   also reset the BIOS clock based on the result, so the correct *   time will be retained across reboots. * * For these reasons, and others, we have continued to use this tool * rather than ntpdate.  It is run automatically at boot time on every * workstation and server in our facility. * * In the past, we called this program 'ntptime'.  Unfortunately, the * ntp v4 distribution also includes a program with that name.  In * order to avoid confusion, we have renamed our program 'ntptimeset', * which more accurately describes what it does. * * Jeffrey T. Hutzelman (N3NHS) <jhutz+@cmu.edu> * School of Computer Science - Research Computing Facility * Carnegie Mellon University - Pittsburgh, PA * 16-Aug-1999 * */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include "ntp_machine.h"#include "ntp_fp.h"#include "ntp.h"#include "ntp_io.h"#include "iosignal.h"#include "ntp_unixtime.h"#include "ntpdate.h"#include "ntp_string.h"#include "ntp_syslog.h"#include "ntp_select.h"#include "ntp_stdlib.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include <stdio.h>#include <signal.h>#include <ctype.h>#ifndef SYS_WINNT# ifdef HAVE_SYS_SIGNAL_H#  include <sys/signal.h># else#  include <signal.h># endif# include <sys/ioctl.h>#endif /* SYS_WINNT */#ifdef HAVE_SYS_RESOURCE_H# include <sys/resource.h>#endif /* HAVE_SYS_RESOURCE_H */#ifdef SYS_VXWORKS# include "ioLib.h"# include "sockLib.h"# include "timers.h"#endif#include "recvbuff.h"#ifdef SYS_WINNT# define TARGET_RESOLUTION 1  /* Try for 1-millisecond accuracy				on Windows NT timers. */#pragma comment(lib, "winmm")#endif /* SYS_WINNT *//* * Scheduling priority we run at */#ifndef SYS_VXWORKS# define	NTPDATE_PRIO	(-12)#else# define	NTPDATE_PRIO	(100)#endif#if defined(HAVE_TIMER_SETTIME) || defined (HAVE_TIMER_CREATE)/* POSIX TIMERS - vxWorks doesn't have itimer - casey */static timer_t ntpdate_timerid;#endif/* * Compatibility stuff for Version 2 */#define NTP_MAXSKW	0x28f	/* 0.01 sec in fp format */#define NTP_MINDIST 0x51f	/* 0.02 sec in fp format */#define NTP_INFIN	15	/* max stratum, infinity a la Bellman-Ford */#define NTP_MAXWGT	(8*FP_SECOND)	/* maximum select weight 8 seconds */#define NTP_MAXLIST 5	/* maximum select list size */#define PEER_SHIFT	8	/* 8 suitable for crystal time base *//* * Debugging flag */volatile int debug = 0;/* * File descriptor masks etc. for call to select */int fd;fd_set fdmask;/* * Initializing flag.  All async routines watch this and only do their * thing when it is clear. */int initializing = 1;/* * Alarm flag.	Set when an alarm occurs */volatile int alarm_flag = 0;/* * Set the time if valid time determined */int set_time = 0;/* * transmission rate control */#define	MINTRANSMITS	(3)	/* minimum total packets per server */#define	MAXXMITCOUNT	(2)	/* maximum packets per time interrupt *//* * time setting constraints */#define	DESIREDDISP	(4*FP_SECOND)	/* desired dispersion, (fp 4) */int max_period = DEFMAXPERIOD;int min_servers = DEFMINSERVERS;int min_valid = DEFMINVALID;/* * counters related to time setting constraints */int contacted = 0;		/* # of servers we have sent to */int responding = 0;		/* servers responding */int validcount = 0;		/* servers with valid time */int valid_n_low = 0;		/* valid time servers with low dispersion *//* * Unpriviledged port flag. */int unpriv_port = 0;/* * Program name. */char *progname;/* * Systemwide parameters and flags */struct server **sys_servers;	/* the server list */int sys_numservers = 0; 	/* number of servers to poll */int sys_authenticate = 0;	/* true when authenticating */u_int32 sys_authkey = 0;	/* set to authentication key in use */u_long sys_authdelay = 0;	/* authentication delay *//* * The current internal time */u_long current_time = 0;/* * File of encryption keys */#ifndef KEYFILE# ifndef SYS_WINNT#define KEYFILE 	"/etc/ntp.keys"# else#define KEYFILE 	"%windir%\\ntp.keys"# endif /* SYS_WINNT */#endif /* KEYFILE */#ifndef SYS_WINNTconst char *key_file = KEYFILE;#elsechar key_file_storage[MAX_PATH+1], *key_file ;#endif	 /* SYS_WINNT *//* * total packet counts */u_long total_xmit = 0;u_long total_recv = 0;/* * Miscellaneous flags */int verbose = 0;#define	HORRIBLEOK	3	/* how many packets to let out */int horrible = 0;	/* how many packets we drop for testing */int secondhalf = 0;	/* second half of timeout period */int printmsg = 0;	/* print time response analysis *//* * The half time and finish time in internal time */u_long half_time = 0;u_long finish_time = 0;int	ntptimesetmain	P((int argc, char *argv[]));static	void	analysis	P((int final));static	int	have_enough	P((void));static	void	transmit	P((register struct server *server));static	void	receive		P((struct recvbuf *rbufp));static	void	clock_filter P((register struct server *server, s_fp d, l_fp *c));static	void	clock_count	P((void));static	struct server *clock_select P((void));static	void	set_local_clock	P((void));static	struct server *findserver P((struct sockaddr_in *addr));static	void	timer		P((void));#ifndef SYS_WINNTstatic	RETSIGTYPE 	alarming	P((int sig));#endif /* SYS_WINNT */static	void	init_alarm	P((void));static	void	init_io		P((void));static	int	sendpkt		P((struct sockaddr_in *dest, struct pkt *pkt, int len));	void 	input_handler	P((l_fp *xts));static	void	printserver	P((register struct server *pp, FILE *fp));#if !defined(HAVE_VSPRINTF)int	vsprintf	P((char *str, const char *fmt, va_list ap));#endif#ifdef HAVE_SIGNALED_IOextern  void    wait_for_signal P((void));extern  void    unblock_io_and_alarm P((void));extern  void    block_io_and_alarm P((void));#endif#ifdef NO_MAIN_ALLOWEDCALL(ntptimeset,"ntptimeset",ntptimesetmain);void clear_globals(){  /*   * Debugging flag   */  debug = 0;  ntp_optind = 0;  /*   * Initializing flag.  All async routines watch this and only do their   * thing when it is clear.   */  initializing = 1;  /*   * Alarm flag.  Set when an alarm occurs   */  alarm_flag = 0;  /*   * Unpriviledged port flag.   */  unpriv_port = 0;  /*   * Systemwide parameters and flags   */  sys_numservers = 0;	  /* number of servers to poll */  sys_authenticate = 0;   /* true when authenticating */  sys_authkey = 0;	   /* set to authentication key in use */  sys_authdelay = 0;   /* authentication delay */  /*   * The current internal time   */  current_time = 0;  verbose = 0;}#endif /* NO_MAIN_ALLOWED *//* * Main program.  Initialize us and loop waiting for I/O and/or * timer expiries. */#ifndef NO_MAIN_ALLOWEDintmain(	int argc,	char *argv[]	){	return ntptimesetmain(argc, argv);}#endif /* NO_MAIN_ALLOWED */	   intntptimesetmain(	int argc,	char *argv[]	){	int was_alarmed;	struct recvbuf *rbuflist;	struct recvbuf *rbuf;	l_fp tmp;	int errflg;	int c;	extern char *ntp_optarg;	extern int ntp_optind;	int ltmp;	char *cfgpath;#ifdef SYS_WINNT	HANDLE process_handle;	wVersionRequested = MAKEWORD(1,1);	if (WSAStartup(wVersionRequested, &wsaData)) {		msyslog(LOG_ERR, "No useable winsock.dll: %m");		exit(1);	}#endif /* SYS_WINNT */#ifdef NO_MAIN_ALLOWED	clear_globals();#endif	errflg = 0;	cfgpath = 0;	progname = argv[0];	syslogit = 0;	/*	 * Decode argument list	 */	while ((c = ntp_getopt(argc, argv, "a:c:de:slt:uvHS:V:")) != EOF)		switch (c)		{		case 'a':			c = atoi(ntp_optarg);			sys_authenticate = 1;			sys_authkey = c;			break;		case 'c':			cfgpath = ntp_optarg;			break;		case 'd':			++debug;			break;		case 'e':			if (!atolfp(ntp_optarg, &tmp)			    || tmp.l_ui != 0) {				(void) fprintf(stderr,				    "%s: encryption delay %s is unlikely\n",				    progname, ntp_optarg);				errflg++;			} else {				sys_authdelay = tmp.l_uf;			}			break;		case 's':			set_time = 1;			break;		case 'l':			syslogit = 1;			break;		case 't':			ltmp = atoi(ntp_optarg);			if (ltmp <= 0) {			    (void) fprintf(stderr,				"%s: maximum time period (%d) is invalid\n",				progname, ltmp);			    errflg++;			}			else			    max_period = ltmp;			break;		case 'u':			unpriv_port = 1;			break;		case 'v':			++verbose;			break;		case 'H':			horrible++;			break;		case 'S':			ltmp = atoi(ntp_optarg);			if (ltmp <= 0) {			    (void) fprintf(stderr,				"%s: minimum responding (%d) is invalid\n",				progname, ltmp);			    errflg++;			}			else			    min_servers = ltmp;			break;		case 'V':			ltmp = atoi(ntp_optarg);			if (ltmp <= 0) {			    (void) fprintf(stderr,				"%s: minimum valid (%d) is invalid\n",				progname, ltmp);			    errflg++;			}			else			    min_valid = ltmp;			break;		case '?':			++errflg;			break;		default:			break;		}		if (errflg || ntp_optind < argc) {		fprintf(stderr,"usage: %s [switches...]\n",progname);		fprintf(stderr,"  -v       (verbose)\n");		fprintf(stderr,"  -c path  (set config file path)\n");		fprintf(stderr,"  -a key   (authenticate using key)\n");		fprintf(stderr,"  -e delay (authentication delay)\n");		fprintf(stderr,"  -S num   (# of servers that must respond)\n");		fprintf(stderr,"  -V num   (# of servers that must valid)\n");		fprintf(stderr,"  -s       (set the time based if okay)\n");		fprintf(stderr,"  -t secs  (time period before ending)\n");		fprintf(stderr,"  -l       (use syslog facility)\n");		fprintf(stderr,"  -u       (use unprivileged port)\n");		fprintf(stderr,"  -H       (drop packets for debugging)\n");		fprintf(stderr,"  -d       (debug output)\n");		exit(2);	}	/*	 * Logging.  Open the syslog if we have to	 */	if (syslogit) {#if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) && !defined SYS_CYGWIN32# ifndef	LOG_DAEMON		openlog("ntptimeset", LOG_PID);# else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -