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

📄 dcfd.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 3 页
字号:
			 * 64 bit machines.... this may cause some of the			 * existing ntp logic to fail for years beyond			 * 2036 (the current 32-bit limit). If all checks			 * fail ONLY beyond year 2036 you may ignore such			 * errors, at least for a decade or so. */    yearend = year0 + year;    year = 1900+YEAR_PIVOT;    printf( "  starting year %04d\n", (int) year );    printf( "  ending year   %04d\n", (int) yearend );    for ( ; year < yearend; year++ )    {	clocktime_t  ct;	time_t	     Observed;	time_t	     Expected;	unsigned     Flag;	unsigned long t;	ct.day = 1;	ct.month = 1;	ct.year = year;	ct.hour = ct.minute = ct.second = ct.usecond = 0;	ct.utcoffset = 0;	ct.flags = 0;	Flag = 0; 	Observed = dcf_to_unixtime( &ct, &Flag );		/* seems to be a clone of parse_to_unixtime() with		 * *a minor difference to arg2 type */	if ( ct.year != year )	{	    fprintf( stdout, 	       "%04d: dcf_to_unixtime(,%d) CORRUPTED ct.year: was %d\n",	       (int)year, (int)Flag, (int)ct.year );	    Error(year);	    break;	}	t = julian0(year) - julian0(1970);	/* Julian day from 1970 */	Expected = t * 24 * 60 * 60;	if ( Observed != Expected  ||  Flag )	{   /* time difference */	    fprintf( stdout, 	       "%04d: dcf_to_unixtime(,%d) FAILURE: was=%lu s/b=%lu  (%ld)\n",	       year, (int)Flag, 	       (unsigned long)Observed, (unsigned long)Expected,	       ((long)Observed - (long)Expected) );	    Error(year);	    break;	}	if ( year >= YEAR_PIVOT+1900 )	{	    /* check year % 100 code we put into dcf_to_unixtime() */	    ct.year = year % 100;	    Flag = 0;	    Observed = dcf_to_unixtime( &ct, &Flag );	    if ( Observed != Expected  ||  Flag )	    {   /* time difference */		fprintf( stdout, "%04d: dcf_to_unixtime(%d,%d) FAILURE: was=%lu s/b=%lu  (%ld)\n",		   year, (int)ct.year, (int)Flag, 		   (unsigned long)Observed, (unsigned long)Expected,		   ((long)Observed - (long)Expected) );		Error(year);		break;	    }	    /* check year - 1900 code we put into dcf_to_unixtime() */	    ct.year = year - 1900;	    Flag = 0;	    Observed = dcf_to_unixtime( &ct, &Flag );	    if ( Observed != Expected  ||  Flag ) {   /* time difference */		    fprintf( stdout, 			     "%04d: dcf_to_unixtime(%d,%d) FAILURE: was=%lu s/b=%lu  (%ld)\n",			     year, (int)ct.year, (int)Flag, 			     (unsigned long)Observed, (unsigned long)Expected,			     ((long)Observed - (long)Expected) );		    Error(year);		break;	    }	}    }    return ( Fatals );}/*-------------------------------------------------- * rawdcf_init - set up modem lines for RAWDCF receivers */#if defined(TIOCMSET) && (defined(TIOCM_DTR) || defined(CIOCM_DTR))static voidrawdcf_init(	int fd	){	/*	 * You can use the RS232 to supply the power for a DCF77 receiver.	 * Here a voltage between the DTR and the RTS line is used. Unfortunately	 * the name has changed from CIOCM_DTR to TIOCM_DTR recently.	 */	#ifdef TIOCM_DTR	int sl232 = TIOCM_DTR;	/* turn on DTR for power supply */#else	int sl232 = CIOCM_DTR;	/* turn on DTR for power supply */#endif	if (ioctl(fd, TIOCMSET, (caddr_t)&sl232) == -1)	{		syslog(LOG_NOTICE, "rawdcf_init: WARNING: ioctl(fd, TIOCMSET, [C|T]IOCM_DTR): %m");	}}#elsestatic voidrawdcf_init(	    int fd	){	syslog(LOG_NOTICE, "rawdcf_init: WARNING: OS interface incapable of setting DTR to power DCF modules");}#endif  /* DTR initialisation type *//*----------------------------------------------------------------------- * main loop - argument interpreter / setup / main loop */intmain(     int argc,     char **argv     ){	unsigned char c;	char **a = argv;	int  ac = argc;	char *file = NULL;	const char *drift_file = "/etc/dcfd.drift";	int fd;	int offset = 15;	int offsets = 0;	int delay = DEFAULT_DELAY;	/* average delay from input edge to time stamping */	int trace = 0;	int errs = 0;	/*	 * process arguments	 */	while (--ac)	{		char *arg = *++a;		if (*arg == '-')		    while ((c = *++arg))			switch (c)			{			    case 't':				trace = 1;				interactive = 1;				break;			    case 'f':				offset = 0;				interactive = 1;				break;			    case 'l':				loop_filter_debug = 1;				offsets = 1;				interactive = 1;				break;			    case 'n':				no_set = 1;				break;			    case 'o':				offsets = 1;				interactive = 1;				break;			    case 'i':				interactive = 1;				break;			    case 'D':				if (ac > 1)				{					delay = atoi(*++a);					ac--;				}				else				{					fprintf(stderr, "%s: -D requires integer argument\n", argv[0]);					errs=1;				}				break;	      			    case 'd':				if (ac > 1)				{					drift_file = *++a;					ac--;				}				else				{					fprintf(stderr, "%s: -d requires file name argument\n", argv[0]);					errs=1;				}				break;	      			    case 'Y':					errs=check_y2k();				exit( errs ? 1 : 0 );			    default:				fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);				errs=1;				break;			}		else		    if (file == NULL)			file = arg;		    else		    {			    fprintf(stderr, "%s: device specified twice\n", argv[0]);			    errs=1;		    }	}	if (errs)	{		usage(argv[0]);		exit(1);	}	else	    if (file == NULL)	    {		    fprintf(stderr, "%s: device not specified\n", argv[0]);		    usage(argv[0]);		    exit(1);	    }	errs = LINES+1;	/*	 * get access to DCF77 tty port	 */	fd = open(file, O_RDONLY);	if (fd == -1)	{		perror(file);		exit(1);	}	else	{		int i, rrc;		struct timeval t, tt, tlast;		struct timeval timeout;		struct timeval phase;		struct timeval time_offset;		char pbuf[61];		/* printable version */		char buf[61];		/* raw data */		clocktime_t clock_time;	/* wall clock time */		time_t utc_time = 0;		time_t last_utc_time = 0;		long usecerror = 0;		long lasterror = 0;#if defined(HAVE_TERMIOS_H) || defined(STREAM)		struct termios term;#else  /* not HAVE_TERMIOS_H || STREAM */# if defined(HAVE_TERMIO_H) || defined(HAVE_SYSV_TTYS)		struct termio term;# endif/* HAVE_TERMIO_H || HAVE_SYSV_TTYS */#endif /* not HAVE_TERMIOS_H || STREAM */		unsigned int rtc = CVT_NONE;		rawdcf_init(fd);				timeout.tv_sec  = 1;		timeout.tv_usec = 500000;		phase.tv_sec    = 0;		phase.tv_usec   = delay;		/*		 * setup TTY (50 Baud, Read, 8Bit, No Hangup, 1 character IO)		 */		if (TTY_GETATTR(fd,  &term) == -1)		{			perror("tcgetattr");			exit(1);		}		memset(term.c_cc, 0, sizeof(term.c_cc));		term.c_cc[VMIN] = 1;#ifdef NO_PARENB_IGNPAR		term.c_cflag = CS8|CREAD|CLOCAL;#else		term.c_cflag = CS8|CREAD|CLOCAL|PARENB;#endif		term.c_iflag = IGNPAR;		term.c_oflag = 0;		term.c_lflag = 0;		cfsetispeed(&term, B50);		cfsetospeed(&term, B50);		if (TTY_SETATTR(fd, &term) == -1)		{			perror("tcsetattr");			exit(1);		}		/*		 * lose terminal if in daemon operation		 */		if (!interactive)		    detach();      		/*		 * get syslog() initialized		 */#ifdef LOG_DAEMON		openlog("dcfd", LOG_PID, LOG_DAEMON);#else		openlog("dcfd", LOG_PID);#endif		/*		 * setup periodic operations (state control / frequency control)		 */#ifdef HAVE_SIGACTION		{			struct sigaction act;			act.sa_handler   = tick;# ifdef HAVE_SA_SIGACTION_IN_STRUCT_SIGACTION			act.sa_sigaction = (void (*) P((int, siginfo_t *, void *)))0;# endif /* HAVE_SA_SIGACTION_IN_STRUCT_SIGACTION */			sigemptyset(&act.sa_mask);			act.sa_flags     = 0;			if (sigaction(SIGALRM, &act, (struct sigaction *)0) == -1)			{				syslog(LOG_ERR, "sigaction(SIGALRM): %m");				exit(1);			}		}#else#ifdef HAVE_SIGVEC		{			struct sigvec vec;			vec.sv_handler   = tick;			vec.sv_mask      = 0;			vec.sv_flags     = 0;			if (sigvec(SIGALRM, &vec, (struct sigvec *)0) == -1)			{				syslog(LOG_ERR, "sigvec(SIGALRM): %m");				exit(1);			}		}#else		(void) signal(SIGALRM, tick);#endif#endif#ifdef ITIMER_REAL		{			struct itimerval it;			it.it_interval.tv_sec  = 1<<ADJINTERVAL;			it.it_interval.tv_usec = 0;			it.it_value.tv_sec     = 1<<ADJINTERVAL;			it.it_value.tv_usec    = 0;				if (setitimer(ITIMER_REAL, &it, (struct itimerval *)0) == -1)			{				syslog(LOG_ERR, "setitimer: %m");				exit(1);			}		}#else		(void) alarm(1<<ADJINTERVAL);#endif		PRINTF("  DCF77 monitor %s - Copyright (C) 1993-2005 by Frank Kardel\n\n", revision);		pbuf[60] = '\0';		for ( i = 0; i < 60; i++)		    pbuf[i] = '.';		read_drift(drift_file);		/*		 * what time is it now (for interval measurement)		 */		gettimeofday(&tlast, 0L);		i = 0;		/*		 * loop until input trouble ...		 */		do		{			/*			 * get an impulse			 */			while ((rrc = read(fd, &c, 1)) == 1)			{				gettimeofday(&t, 0L);				tt = t;				timersub(&t, &tlast);				if (errs > LINES)				{					PRINTF("  %s", &"PTB private....RADMLSMin....PHour..PMDay..DayMonthYear....P\n"[offset]);					PRINTF("  %s", &"---------------RADMLS1248124P124812P1248121241248112481248P\n"[offset]);					errs = 0;				}				/*				 * timeout -> possible minute mark -> interpretation				 */				if (timercmp(&t, &timeout, >))				{					PRINTF("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &pbuf[offset]);					if ((rtc = cvt_rawdcf((unsigned char *)buf, i, &clock_time)) != CVT_OK)					{						/*						 * this data was bad - well - forget synchronisation for now						 */						PRINTF("\n");						if (sync_state == SYNC)						{							sync_state = NO_SYNC;							syslog(LOG_INFO, "DCF77 reception lost (bad data)");						}						errs++;					}					else					    if (trace)					    {						    PRINTF("\r  %.*s ", 59 - offset, &buf[offset]);					    }					buf[0] = c;					/*					 * collect first character					 */					if (((c^0xFF)+1) & (c^0xFF))					    pbuf[0] = '?';					else					    pbuf[0] = type(c) ? '#' : '-';					for ( i = 1; i < 60; i++)					    pbuf[i] = '.';					i = 0;				}				else				{					/*					 * collect character					 */					buf[i] = c;					/*					 * initial guess (usually correct)					 */					if (((c^0xFF)+1) & (c^0xFF))					    pbuf[i] = '?';					else					    pbuf[i] = type(c) ? '#' : '-';					PRINTF("%c %.*s ", pat[i % (sizeof(pat)-1)], 59 - offset, &pbuf[offset]);				}				if (i == 0 && rtc == CVT_OK)				{					/*					 * we got a good time code here - try to convert it to					 * UTC					 */					if ((utc_time = dcf_to_unixtime(&clock_time, &rtc)) == -1)					{						PRINTF("*** BAD CONVERSION\n");					}					if (utc_time != (last_utc_time + 60))					{						/*						 * well, two successive sucessful telegrams are not 60 seconds						 * apart						 */						PRINTF("*** NO MINUTE INC\n");						if (sync_state == SYNC)						{							sync_state = NO_SYNC;							syslog(LOG_INFO, "DCF77 reception lost (data mismatch)");						}						errs++;						rtc = CVT_FAIL|CVT_BADTIME|CVT_BADDATE;					}					else					    usecerror = 0;					last_utc_time = utc_time;				}				if (rtc == CVT_OK)				{					if (i == 0)					{						/*						 * valid time code - determine offset and						 * note regained reception						 */						last_sync = ticks;						if (sync_state == NO_SYNC)						{							syslog(LOG_INFO, "receiving DCF77");						}						else						{							/*							 * we had at least one minute SYNC - thus							 * last error is valid							 */							time_offset.tv_sec  = lasterror / 1000000;							time_offset.tv_usec = lasterror % 1000000;							adjust_clock(&time_offset, drift_file, utc_time);						}						sync_state = SYNC;					}					time_offset.tv_sec  = utc_time + i;					time_offset.tv_usec = 0;					timeradd(&time_offset, &phase);					usecerror += (time_offset.tv_sec - tt.tv_sec) * 1000000 + time_offset.tv_usec						-tt.tv_usec;					/*					 * output interpreted DCF77 data					 */					PRINTF(offsets ? "%s, %2ld:%02ld:%02d, %ld.%02ld.%02ld, <%s%s%s%s> (%c%ld.%06lds)" :					       "%s, %2ld:%02ld:%02d, %ld.%02ld.%02ld, <%s%s%s%s>",					       wday[clock_time.wday],					       clock_time.hour, clock_time.minute, i, clock_time.day, clock_time.month,					       clock_time.year,					       (clock_time.flags & DCFB_ALTERNATE) ? "R" : "_",					       (clock_time.flags & DCFB_ANNOUNCE) ? "A" : "_",					       (clock_time.flags & DCFB_DST) ? "D" : "_",					       (clock_time.flags & DCFB_LEAP) ? "L" : "_",					       (lasterror < 0) ? '-' : '+', l_abs(lasterror) / 1000000, l_abs(lasterror) % 1000000					       );					if (trace && (i == 0))					{						PRINTF("\n");						errs++;					}					lasterror = usecerror / (i+1);				}				else				{					lasterror = 0; /* we cannot calculate phase errors on bad reception */				}				PRINTF("\r");				if (i < 60)				{					i++;				}				tlast = tt;				if (interactive)				    fflush(stdout);			}		} while ((rrc == -1) && (errno == EINTR));      		/*		 * lost IO - sorry guys		 */		syslog(LOG_ERR, "TERMINATING - cannot read from device %s (%m)", file);		(void)close(fd);	}	closelog();  	return 0;}/* * History: * * dcfd.c,v * Revision 4.18  2005/10/07 22:08:18  kardel * make dcfd.c compile on NetBSD 3.99.9 again (configure/sigvec compatibility fix) * * Revision 4.17.2.1  2005/10/03 19:15:16  kardel * work around configure not detecting a missing sigvec compatibility * interface on NetBSD 3.99.9 and above * * Revision 4.17  2005/08/10 10:09:44  kardel * output revision information * * Revision 4.16  2005/08/10 06:33:25  kardel * cleanup warnings * * Revision 4.15  2005/08/10 06:28:45  kardel * fix setting of baud rate * * Revision 4.14  2005/04/16 17:32:10  kardel * update copyright * * Revision 4.13  2004/11/14 15:29:41  kardel * support PPSAPI, upgrade Copyright to Berkeley style * */

⌨️ 快捷键说明

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