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

📄 parse.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * /src/NTP/ntp4-dev/libparse/parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A *   * parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A * * Parser module for reference clock * * PARSEKERNEL define switches between two personalities of the module * if PARSEKERNEL is defined this module can be used * as kernel module. In this case the time stamps will be * a struct timeval. * when PARSEKERNEL is not defined NTP time stamps will be used. * * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org> * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universit鋞 Erlangen-N黵nberg, Germany * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#ifdef HAVE_CONFIG_H# include <config.h>#endif#if defined(REFCLOCK) && defined(CLOCK_PARSE)#if	!(defined(lint) || defined(__GNUC__))static char rcsid[] = "parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A";#endif#include "ntp_fp.h"#include "ntp_unixtime.h"#include "ntp_calendar.h"#include "ntp_stdlib.h"#include "ntp_machine.h"#include "ntp.h"		/* (get Y2KFixes definitions) 	Y2KFixes */#include "parse.h"#ifndef PARSESTREAM# include <stdio.h>#else# include "sys/parsestreams.h"#endifextern clockformat_t *clockformats[];extern unsigned short nformats;static u_long timepacket P((parse_t *));/* * strings support usually not in kernel - duplicated, but what the heck */static intStrlen(	register const char *s	){	register int c;	c = 0;	if (s)	{		while (*s++)		{			c++;		}	}	return c;}static intStrcmp(	register const char *s,	register const char *t	){	register int c = 0;	if (!s || !t || (s == t))	{		return 0;	}	while (!(c = *s++ - *t++) && *s && *t)	    /* empty loop */;  	return c;}intparse_timedout(	       parse_t *parseio,	       timestamp_t *tstamp,	       struct timeval *del	       ){	struct timeval delta;#ifdef PARSEKERNEL	delta.tv_sec = tstamp->tv.tv_sec - parseio->parse_lastchar.tv.tv_sec;	delta.tv_usec = tstamp->tv.tv_usec - parseio->parse_lastchar.tv.tv_usec;	if (delta.tv_usec < 0)	{		delta.tv_sec  -= 1;		delta.tv_usec += 1000000;	}#else	extern long tstouslo[];	extern long tstousmid[];	extern long tstoushi[];	l_fp delt;	delt = tstamp->fp;	L_SUB(&delt, &parseio->parse_lastchar.fp);	TSTOTV(&delt, &delta);#endif	if (timercmp(&delta, del, >))	{		parseprintf(DD_PARSE, ("parse: timedout: TRUE\n"));		return 1;	}	else	{		parseprintf(DD_PARSE, ("parse: timedout: FALSE\n"));		return 0;	}}/*ARGSUSED*/intparse_ioinit(	register parse_t *parseio	){	parseprintf(DD_PARSE, ("parse_iostart\n"));  	parseio->parse_plen = 0;	parseio->parse_pdata = (void *)0;  	parseio->parse_data = 0;	parseio->parse_ldata = 0;	parseio->parse_dsize = 0;	parseio->parse_badformat = 0;	parseio->parse_ioflags   = PARSE_IO_CS7;	/* usual unix default */	parseio->parse_index     = 0;	parseio->parse_ldsize    = 0;  	return 1;}/*ARGSUSED*/voidparse_ioend(	register parse_t *parseio	){	parseprintf(DD_PARSE, ("parse_ioend\n"));	if (parseio->parse_pdata)	    FREE(parseio->parse_pdata, parseio->parse_plen);	if (parseio->parse_data)	    FREE(parseio->parse_data, (unsigned)(parseio->parse_dsize * 2 + 2));}unsigned intparse_restart(	      parse_t *parseio,	      unsigned int ch	      ){	unsigned int updated = PARSE_INP_SKIP;		/*	 * re-start packet - timeout - overflow - start symbol	 */		if (parseio->parse_index)	{		/*		 * filled buffer - thus not end character found		 * do processing now		 */		parseio->parse_data[parseio->parse_index] = '\0';		memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));		parseio->parse_ldsize = parseio->parse_index;		updated = PARSE_INP_TIME;	}			parseio->parse_index = 1;	parseio->parse_data[0] = ch;	parseprintf(DD_PARSE, ("parse: parse_restart: buffer start (updated = %x)\n", updated));	return updated;}	unsigned intparse_addchar(	      parse_t *parseio,	      unsigned int ch	      ){	/*	 * add to buffer	 */	if (parseio->parse_index < parseio->parse_dsize)	{		/*		 * collect into buffer		 */		parseprintf(DD_PARSE, ("parse: parse_addchar: buffer[%d] = 0x%x\n", parseio->parse_index, ch));		parseio->parse_data[parseio->parse_index++] = ch;		return PARSE_INP_SKIP;	}	else		/*		 * buffer overflow - attempt to make the best of it		 */		return parse_restart(parseio, ch);}	unsigned intparse_end(	  parse_t *parseio	  ){	/*	 * message complete processing	 */	parseio->parse_data[parseio->parse_index] = '\0';	memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));	parseio->parse_ldsize = parseio->parse_index;	parseio->parse_index = 0;	parseprintf(DD_PARSE, ("parse: parse_end: buffer end\n"));	return PARSE_INP_TIME;}/*ARGSUSED*/intparse_ioread(	register parse_t *parseio,	register unsigned int ch,	register timestamp_t *tstamp	){	register unsigned updated = CVT_NONE;	/*	 * within STREAMS CSx (x < 8) chars still have the upper bits set	 * so we normalize the characters by masking unecessary bits off.	 */	switch (parseio->parse_ioflags & PARSE_IO_CSIZE)	{	    case PARSE_IO_CS5:		ch &= 0x1F;		break;	    case PARSE_IO_CS6:		ch &= 0x3F;		break;	    case PARSE_IO_CS7:		ch &= 0x7F;		break;      	    case PARSE_IO_CS8:		ch &= 0xFF;		break;	}	parseprintf(DD_PARSE, ("parse_ioread(0x%lx, char=0x%x, ..., ...)\n", (unsigned long)parseio, ch & 0xFF));	if (!clockformats[parseio->parse_lformat]->convert)	{		parseprintf(DD_PARSE, ("parse_ioread: input dropped.\n"));		return CVT_NONE;	}	if (clockformats[parseio->parse_lformat]->input)	{		unsigned long input_status;		input_status = clockformats[parseio->parse_lformat]->input(parseio, ch, tstamp);		if (input_status & PARSE_INP_SYNTH)		{			updated = CVT_OK;		}				if (input_status & PARSE_INP_TIME)	/* time sample is available */		{			updated = timepacket(parseio);		}		  		if (input_status & PARSE_INP_DATA) /* got additional data */		{			updated |= CVT_ADDITIONAL;		}	}		/*	 * remember last character time	 */	parseio->parse_lastchar = *tstamp;#ifdef DEBUG	if ((updated & CVT_MASK) != CVT_NONE)	{		parseprintf(DD_PARSE, ("parse_ioread: time sample accumulated (status=0x%x)\n", updated));	}#endif	parseio->parse_dtime.parse_status = updated;	return (((updated & CVT_MASK) != CVT_NONE) ||		((updated & CVT_ADDITIONAL) != 0));}/* * parse_iopps * * take status line indication and derive synchronisation information * from it. * It can also be used to decode a serial serial data format (such as the * ONE, ZERO, MINUTE sync data stream from DCF77) *//*ARGSUSED*/intparse_iopps(	register parse_t *parseio,	register int status,	register timestamp_t *ptime	){	register unsigned updated = CVT_NONE;	/*	 * PPS pulse information will only be delivered to ONE clock format	 * this is either the last successful conversion module with a ppssync	 * routine, or a fixed format with a ppssync routine	 */	parseprintf(DD_PARSE, ("parse_iopps: STATUS %s\n", (status == SYNC_ONE) ? "ONE" : "ZERO"));	if (clockformats[parseio->parse_lformat]->syncpps)	{		updated = clockformats[parseio->parse_lformat]->syncpps(parseio, status == SYNC_ONE, ptime);		parseprintf(DD_PARSE, ("parse_iopps: updated = 0x%x\n", updated));	}	return (updated & CVT_MASK) != CVT_NONE;}/* * parse_iodone * * clean up internal status for new round *//*ARGSUSED*/voidparse_iodone(	register parse_t *parseio	){	/*	 * we need to clean up certain flags for the next round	 */	parseprintf(DD_PARSE, ("parse_iodone: DONE\n"));	parseio->parse_dtime.parse_state = 0; /* no problems with ISRs */}/*---------- conversion implementation --------------------*//* * convert a struct clock to UTC since Jan, 1st 1970 0:00 (the UNIX EPOCH) */#define days_per_year(x)	((x) % 4 ? 365 : ((x % 400) ? ((x % 100) ? 366 : 365) : 366))time_tparse_to_unixtime(	register clocktime_t   *clock_time,	register u_long *cvtrtc	){#define SETRTC(_X_)	{ if (cvtrtc) *cvtrtc = (_X_); }	static int days_of_month[] = 	{		0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31	};	register int i;	time_t t;  	if (clock_time->utctime)	    return clock_time->utctime;	/* if the conversion routine gets it right away - why not */	if ( clock_time->year < YEAR_PIVOT )			/* Y2KFixes [ */	    clock_time->year += 100;	/* convert 20xx%100 to 20xx-1900 */	if ( clock_time->year < YEAR_BREAK )	/* expand to full four-digits */	    clock_time->year += 1900;	if (clock_time->year < 1970 )				/* Y2KFixes ] */	{		SETRTC(CVT_FAIL|CVT_BADDATE);		return -1;	}  	/*	 * sorry, slow section here - but it's not time critical anyway	 */	t = julian0(clock_time->year) - julian0(1970);		/* Y2kFixes */  				/* month */	if (clock_time->month <= 0 || clock_time->month > 12)	{		SETRTC(CVT_FAIL|CVT_BADDATE);		return -1;		/* bad month */	}#if 0								/* Y2KFixes */				/* adjust leap year */	if (clock_time->month < 3 && days_per_year(clock_time->year) == 366)	    t--;#else								/* Y2KFixes [ */	if ( clock_time->month >= 3  &&  isleap_4(clock_time->year) )	    t++;		/* add one more if within leap year */#endif								/* Y2KFixes ] */	for (i = 1; i < clock_time->month; i++)	{		t += days_of_month[i];	}				/* day */	if (clock_time->day < 1 || ((clock_time->month == 2 && days_per_year(clock_time->year) == 366) ?			       clock_time->day > 29 : clock_time->day > days_of_month[clock_time->month]))	{		SETRTC(CVT_FAIL|CVT_BADDATE);		return -1;		/* bad day */	}	t += clock_time->day - 1;				/* hour */	if (clock_time->hour < 0 || clock_time->hour >= 24)	{		SETRTC(CVT_FAIL|CVT_BADTIME);		return -1;		/* bad hour */	}	t = TIMES24(t) + clock_time->hour;  				/* min */	if (clock_time->minute < 0 || clock_time->minute > 59)	{

⌨️ 快捷键说明

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