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

📄 ntp_config.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
	info_auth_keyid = req_keyid;#endif /* !defined(VMS) && !defined(SYS_VXWORKS) */	if (res_fp != NULL) {		if (call_resolver) {			/*			 * Need name resolution			 */			do_resolve_internal();		}	}}#ifdef HAVE_NETINFO/*  * get_netinfo_config - find the nearest NetInfo domain with an ntp * configuration and initialize the configuration state. */static struct netinfo_config_state *get_netinfo_config(){	ni_status status;	void *domain;	ni_id config_dir;       	struct netinfo_config_state *config;	if (ni_open(NULL, ".", &domain) != NI_OK) return NULL;	while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) {		void *next_domain;		if (ni_open(domain, "..", &next_domain) != NI_OK) {			ni_free(next_domain);			break;		}		ni_free(domain);		domain = next_domain;	}	if (status != NI_OK) {		ni_free(domain);		return NULL;	}       	config = (struct netinfo_config_state *)malloc(sizeof(struct netinfo_config_state));       	config->domain = domain;       	config->config_dir = config_dir;       	config->prop_index = 0;       	config->val_index = 0;       	config->val_list = NULL;	return config;}/* * free_netinfo_config - release NetInfo configuration state */static voidfree_netinfo_config(struct netinfo_config_state *config){	ni_free(config->domain);	free(config);}/* * gettokens_netinfo - return tokens from NetInfo */static intgettokens_netinfo (	struct netinfo_config_state *config,	char **tokenlist,	int *ntokens	){	int prop_index = config->prop_index;	int val_index = config->val_index;	char **val_list = config->val_list;	/*	 * Iterate through each keyword and look for a property that matches it.	 */	again:	if (!val_list) {	       	for (; prop_index < (sizeof(keywords)/sizeof(keywords[0])); prop_index++)	       	{		       	ni_namelist namelist;			struct keyword current_prop = keywords[prop_index];			/*			 * For each value associated in the property, we're going to return			 * a separate line. We squirrel away the values in the config state			 * so the next time through, we don't need to do this lookup.			 */		       	NI_INIT(&namelist);	       		if (ni_lookupprop(config->domain, &config->config_dir, current_prop.text, &namelist) == NI_OK) {				ni_index index;				/* Found the property, but it has no values */				if (namelist.ni_namelist_len == 0) continue;				if (! (val_list = config->val_list = (char**)malloc(sizeof(char*) * (namelist.ni_namelist_len + 1))))					{ msyslog(LOG_ERR, "out of memory while configuring"); break; }				for (index = 0; index < namelist.ni_namelist_len; index++) {					char *value = namelist.ni_namelist_val[index];					if (! (val_list[index] = (char*)malloc(strlen(value)+1)))						{ msyslog(LOG_ERR, "out of memory while configuring"); break; }					strcpy(val_list[index], value);				}				val_list[index] = NULL;				break;			}			ni_namelist_free(&namelist);		}		config->prop_index = prop_index;	}	/* No list; we're done here. */       	if (!val_list) return CONFIG_UNKNOWN;	/*	 * We have a list of values for the current property.	 * Iterate through them and return each in order.	 */	if (val_list[val_index])	{		int ntok = 1;		int quoted = 0;		char *tokens = val_list[val_index];		msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]);		(const char*)tokenlist[0] = keywords[prop_index].text;		for (ntok = 1; ntok < MAXTOKENS; ntok++) {			tokenlist[ntok] = tokens;			while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted))				quoted ^= (*tokens++ == '"');			if (ISEOL(*tokens)) {				*tokens = '\0';				break;			} else {		/* must be space */				*tokens++ = '\0';				while (ISSPACE(*tokens)) tokens++;				if (ISEOL(*tokens)) break;			}		}		if (ntok == MAXTOKENS) {			/* HMS: chomp it to lose the EOL? */			msyslog(LOG_ERR,			    "gettokens_netinfo: too many tokens.  Ignoring: %s",			    tokens);		} else {			*ntokens = ntok + 1;		}		config->val_index++;	/* HMS: Should this be in the 'else'? */		return keywords[prop_index].keytype;	}	/* We're done with the current property. */	prop_index = ++config->prop_index;	/* Free val_list and reset counters. */	for (val_index = 0; val_list[val_index]; val_index++)		free(val_list[val_index]);       	free(val_list);	val_list = config->val_list = NULL; val_index = config->val_index = 0;	goto again;}#endif /* HAVE_NETINFO *//* * gettokens - read a line and return tokens */static intgettokens (	FILE *fp,	char *line,	char **tokenlist,	int *ntokens	){	register char *cp;	register int ntok;	register int quoted = 0;	/*	 * Find start of first token	 */	again:	while ((cp = fgets(line, MAXLINE, fp)) != NULL) {		cp = line;		while (ISSPACE(*cp))			cp++;		if (!ISEOL(*cp))			break;	}	if (cp == NULL) {		*ntokens = 0;		return CONFIG_UNKNOWN;	/* hack.  Is recognized as EOF */	}	/*	 * Now separate out the tokens	 */	for (ntok = 0; ntok < MAXTOKENS; ntok++) {		tokenlist[ntok] = cp;		while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted))			quoted ^= (*cp++ == '"');		if (ISEOL(*cp)) {			*cp = '\0';			break;		} else {		/* must be space */			*cp++ = '\0';			while (ISSPACE(*cp))				cp++;			if (ISEOL(*cp))				break;		}	}     /* Heiko: Remove leading and trailing quotes around tokens */     {            int i,j = 0;	    					for (i = 0; i < ntok; i++) {	    					/* Now check if the first char is a quote and remove that */					if ( tokenlist[ntok][0] == '"' )							tokenlist[ntok]++;					/* Now check the last char ... */					j = strlen(tokenlist[ntok])-1;					if ( tokenlist[ntok][j] == '"' )							tokenlist[ntok][j] = '\0';			}							    }	if (ntok == MAXTOKENS) {		--ntok;		/* HMS: chomp it to lose the EOL? */		msyslog(LOG_ERR,		    "gettokens: too many tokens on the line. Ignoring %s",		    cp);	} else {		/*		 * Return the match		 */		*ntokens = ntok + 1;		ntok = matchkey(tokenlist[0], keywords, 1);		if (ntok == CONFIG_UNKNOWN)			goto again;	}	return ntok;}/* * matchkey - match a keyword to a list */static intmatchkey(	register char *word,	register struct keyword *keys,	int complain	){	for (;;) {		if (keys->keytype == CONFIG_UNKNOWN) {			if (complain)				msyslog(LOG_ERR,				    "configure: keyword \"%s\" unknown, line ignored",				    word);			return CONFIG_UNKNOWN;		}		if (STRSAME(word, keys->text))			return keys->keytype;		keys++;	}}/* * getnetnum - return a net number (this is crude, but careful) */static intgetnetnum(	const char *num,	struct sockaddr_storage *addr,	int complain,	enum gnn_type a_type	){	struct addrinfo hints;	struct addrinfo *ptr;	int retval;	/* Get host address. Looking for UDP datagram connection */ 	memset(&hints, 0, sizeof (hints)); 	if (addr->ss_family == AF_INET || addr->ss_family == AF_INET6)	    hints.ai_family = addr->ss_family;	else	    hints.ai_family = AF_UNSPEC;	/*	 * If we don't have an IPv6 stack, just look up IPv4 addresses	 */	if (isc_net_probeipv6() != ISC_R_SUCCESS)		hints.ai_family = AF_INET;	hints.ai_socktype = SOCK_DGRAM;#ifdef DEBUG		if (debug > 3)			printf("getaddrinfo %s\n", num);#endif	retval = getaddrinfo(num, "ntp", &hints, &ptr);	if (retval != 0 ||	   (ptr->ai_family == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) {		if (complain)			msyslog(LOG_ERR,				"getaddrinfo: \"%s\" invalid host address, ignored",				num);#ifdef DEBUG		if (debug > 0)			printf(				"getaddrinfo: \"%s\" invalid host address%s.\n",				num, (complain)				? ", ignored"				: "");#endif		if (retval == 0 && 		    ptr->ai_family == AF_INET6 && 		    isc_net_probeipv6() != ISC_R_SUCCESS) 		{			return -1;		}		else {			return 0;		}	}	memcpy(addr, ptr->ai_addr, ptr->ai_addrlen);#ifdef DEBUG	if (debug > 1)		printf("getnetnum given %s, got %s \n",		   num, stoa(addr));#endif        freeaddrinfo(ptr);	return 1;}#if !defined(VMS) && !defined(SYS_WINNT)/* * catchchild - receive the resolver's exit status */static RETSIGTYPEcatchchild(	int sig	){	/*	 * We only start up one child, and if we're here	 * it should have already exited.  Hence the following	 * shouldn't hang.  If it does, please tell me.	 */#if !defined (SYS_WINNT) && !defined(SYS_VXWORKS)	(void) wait(0);#endif /* SYS_WINNT  && VXWORKS*/}#endif /* VMS *//* * save_resolve - save configuration info into a file for later name resolution */static voidsave_resolve(	char *name,	int mode,	int version,	int minpoll,	int maxpoll,	u_int flags,	int ttl,	keyid_t keyid,	u_char *keystr	){#ifndef SYS_VXWORKS	if (res_fp == NULL) {#ifndef SYS_WINNT		(void) strcpy(res_file, RES_TEMPFILE);#else		/* no /tmp directory under NT */		{			if(!(GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) {				msyslog(LOG_ERR, "cannot get pathname for temporary directory: %m");				return;			}			(void) strcat(res_file, "ntpdXXXXXX");		}#endif /* SYS_WINNT */#ifdef HAVE_MKSTEMP		{			int fd;			res_fp = NULL;			if ((fd = mkstemp(res_file)) != -1)				res_fp = fdopen(fd, "r+");		}#else		(void) mktemp(res_file);		res_fp = fopen(res_file, "w");#endif		if (res_fp == NULL) {			msyslog(LOG_ERR, "open failed for %s: %m", res_file);			return;		}	}#ifdef DEBUG	if (debug) {		printf("resolving %s\n", name);	}#endif	(void)fprintf(res_fp, "%s %d %d %d %d %d %d %u %s\n", name,	    mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr);#ifdef DEBUG	if (debug > 1)		printf("config: %s %d %d %d %d %x %d %u %s\n", name, mode,		    version, minpoll, maxpoll, flags, ttl, keyid, keystr);#endif#else  /* SYS_VXWORKS */	/* save resolve info to a struct */#endif /* SYS_VXWORKS */}/* * abort_resolve - terminate the resolver stuff and delete the file */static voidabort_resolve(void){	/*	 * In an ideal world we would might reread the file and	 * log the hosts which aren't getting configured.  Since	 * this is too much work, however, just close and delete	 * the temp file.	 */	if (res_fp != NULL)		(void) fclose(res_fp);	res_fp = NULL;#ifndef SYS_VXWORKS		/* we don't open the file to begin with */#if !defined(VMS)	(void) unlink(res_file);#else	(void) delete(res_file);#endif /* VMS */#endif /* SYS_VXWORKS */}/* * do_resolve_internal - start up the resolver function (not program) *//* * On VMS, this routine will simply refuse to resolve anything. * * Possible implementation: keep `res_file' in memory, do async * name resolution via QIO, update from within completion AST. * I'm unlikely to find the time for doing this, though. -wjm */static voiddo_resolve_internal(void){	int i;	if (res_fp == NULL) {		/* belch */		msyslog(LOG_ERR,			"do_resolve_internal: Fatal: res_fp == NULL");		exit(1);	}	/* we are done with this now */	(void) fclose(res_fp);	res_fp = NULL;#if !defined(VMS) && !defined (SYS_VXWORKS)	req_file = res_file;	/* set up pointer to res file */#ifndef SYS_WINNT	(void) signal_no_reset(SIGCHLD, catchchild);#ifndef SYS_VXWORKS	i = fork();	if (i == 0) {		/*		 * this used to close everything		 * I don't think this is necessary		 */		/*		 * To the unknown commenter above:		 * Well, I think it's better to clean up		 * after oneself. I have had problems with		 * refclock-io when intres was running - things		 * where fine again when ntpintres was gone.		 * So some systems react erratic at least.		 *		 *			Frank Kardel		 *		 * 94-11-16:		 * Further debugging has proven that the above is		 * absolutely harmful. The internal resolver		 * is still in the SIGIO process group and the lingering		 * async io information causes it to process requests from		 * all file decriptor causing a race between the NTP daemon		 * and the resolver. which then eats data when it wins 8-(.		 * It is absolutly necessary to kill any IO associations		 * shared with the NTP daemon.		 *		 * We also block SIGIO (currently no ports means to		 * disable the signal handle for IO).		 *		 * Thanks to wgstuken@informatik.uni-erlangen.de to notice		 * that it is the ntp-resolver child running into trouble.		 *		 * THUS:		 */		closelog();		kill_asyncio(0);		(void) signal_no_reset(SIGCHLD, SIG_DFL);#ifdef DEBUG		if (0)		    debug = 2;#endif# ifndef LOG_DAEMON		openlog("ntpd_initres", LOG_PID);# else /* LOG_DAEMON */#  ifndef LOG_NTP#   define	LOG_NTP LOG_DAEMON#  endif		openlog("ntpd_initres", LOG_PID | LOG_NDELAY, LOG_NTP);#ifndef SYS_CYGWIN32#  ifdef DEBUG		if (debug)		    setlogmask(LOG_UPTO(LOG_DEBUG));		else#  endif /* DEBUG */		    setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */# endif /* LOG_DAEMON */#endif		ntp_intres();		/*		 * If we got here, the intres code screwed up.		 * Print something so we don't die without complaint		 */		msyslog(LOG_ERR, "call to ntp_intres lost");		abort_resolve();		exit(1);	}#else	 /* vxWorks spawns a thread... -casey */	 i = sp (ntp_intres);	 /*i = taskSpawn("ntp_intres",100,VX_FP_TASK,20000,ntp_intres);*/#endif	if (i == -1) {		msyslog(LOG_ERR, "fork() failed, can't start ntp_intres: %m");		(void) signal_no_reset(SIGCHLD, SIG_DFL);		abort_resolve();	}#else /* SYS_WINNT */	{		/* NT's equivalent of fork() is _spawn(), but the start point		 * of the new process is an executable filename rather than		 * a function name as desired here.		 */		DWORD dwThreadId;		fflush(stdout);		ResolverThreadHandle = CreateThread(			NULL,				 /* no security attributes	*/			0,				 /* use default stack size	*/			(LPTHREAD_START_ROUTINE) ntp_intres, /* thread function		*/			NULL,				 /* argument to thread function   */			0,				 /* use default creation flags	  */			&dwThreadId);			 /* returns the thread identifier */		if (ResolverThreadHandle == NULL) {			msyslog(LOG_ERR, "CreateThread() failed, can't start ntp_intres");			abort_resolve();		}	}#endif /* SYS_WINNT */#else /* VMS  VX_WORKS */	msyslog(LOG_ERR,		"Name resolution not implemented for VMS - use numeric addresses");	abort_resolve();#endif /* VMS VX_WORKS */}

⌨️ 快捷键说明

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