home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xntp3.zip
/
xntpd
/
ntpd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-29
|
8KB
|
393 lines
/*
* ntpd.c - main program for the fixed point NTP daemon
*/
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include "ntp_syslog.h"
#include "ntp_fp.h"
#include "ntp.h"
#if defined(ULT_2_0_SUCKS)
#ifndef sigmask
#define sigmask(m) (1<<(m))
#endif
#endif
/*
* Mask for blocking SIGIO and SIGALRM
*/
#define BLOCKSIGMASK (sigmask(SIGIO)|sigmask(SIGALRM))
/*
* Signals we catch for debugging. If not debugging we ignore them.
*/
#define MOREDEBUGSIG SIGUSR1
#define LESSDEBUGSIG SIGUSR2
/*
* Signals which terminate us gracefully.
*/
#define SIGDIE1 SIGHUP
#define SIGDIE2 SIGINT
#define SIGDIE3 SIGQUIT
#define SIGDIE4 SIGTERM
/*
* Scheduling priority we run at
*/
#define NTPD_PRIO (-12)
/*
* Debugging flag
*/
int debug;
/*
* Initializing flag. All async routines watch this and only do their
* thing when it is clear.
*/
int initializing;
/*
* Version declaration
*/
extern char *Version;
/*
* Alarm flag. Imported from timer module
*/
extern int alarm_flag;
/*
* Main program. Initialize us, disconnect us from the tty if necessary,
* and loop waiting for I/O and/or timer expiries.
*/
main(argc, argv)
int argc;
char *argv[];
{
char *cp;
int was_alarmed;
struct recvbuf *rbuflist;
struct recvbuf *rbuf;
extern struct recvbuf *getrecvbufs();
extern void getstartup();
extern char *rindex();
#ifdef DEBUG
void moredebug(), lessdebug();
#endif
#ifdef SIGDIE1
void finish();
#endif /* SIGDIE1 */
initializing = 1; /* mark that we are initializing */
debug = 0; /* no debugging by default */
getstartup(argc, argv); /* startup configuration, may set debug */
#ifndef NODETACH
/*
* Detach us from the terminal. May need an #ifndef GIZMO.
*/
#ifdef DEBUG
if (!debug) {
#endif
#if BSD >= 199006
daemon(0, 0);
#else
if (fork())
exit(0);
{
int s;
for (s = getdtablesize(); s >= 0; s--)
(void) close(s);
(void) open("/", 0);
(void) dup2(0, 1);
(void) dup2(0, 2);
#if defined(HPUX)
(void) setsid();
#else
(void) setpgrp(0, getpid());
#endif
#if defined(HPUX)
if (fork())
exit(0);
#else
#ifdef apollo
/*
* This breaks... the program fails to listen to any packets coming
* in on the UDP socket. So how do you break terminal affiliation?
*/
#else
s = open("/dev/tty", 2);
if (s >= 0) {
(void) ioctl(s, (u_long) TIOCNOTTY, (char *) 0);
(void) close(s);
}
#endif
#endif
}
#endif
#ifdef DEBUG
}
#endif
#endif /* NODETACH */
/*
* Logging. This may actually work on the gizmo board. Find a name
* to log with by using the basename of argv[0]
*/
cp = rindex(argv[0], '/');
if (cp == 0)
cp = argv[0];
else
cp++;
#ifndef LOG_DAEMON
openlog(cp, LOG_PID);
#else
#ifndef LOG_NTP
#define LOG_NTP LOG_DAEMON
#endif
openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);
#ifdef DEBUG
if (debug)
setlogmask(LOG_UPTO(LOG_DEBUG));
else
#endif /* DEBUG */
setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
#endif /* LOG_DAEMON */
syslog(LOG_INFO, Version);
/*
* Set the priority.
*/
#if !defined(HPUX)
#if defined(NTPD_PRIO) && NTPD_PRIO != 0
(void) setpriority(PRIO_PROCESS, 0, NTPD_PRIO);
#endif /* ... */
#endif
/*
* Set up signals we pay attention to locally.
*/
#ifdef SIGDIE1
(void) signal(SIGDIE1, finish);
#endif /* SIGDIE1 */
#ifdef SIGDIE2
(void) signal(SIGDIE2, finish);
#endif /* SIGDIE2 */
#ifdef SIGDIE3
(void) signal(SIGDIE3, finish);
#endif /* SIGDIE3 */
#ifdef SIGDIE4
(void) signal(SIGDIE4, finish);
#endif /* SIGDIE4 */
#ifdef DEBUG
(void) signal(MOREDEBUGSIG, moredebug);
(void) signal(LESSDEBUGSIG, lessdebug);
#else
(void) signal(MOREDEBUGSIG, SIG_IGN);
(void) signal(LESSDEBUGSIG, SIG_IGN);
#endif /* DEBUG */
/*
* Call the init_ routines to initialize the data structures.
* Note that init_systime() may run a protocol to get a crude
* estimate of the time as an NTP client when running on the
* gizmo board. It is important that this be run before
* init_subs() since the latter uses the time of day to seed
* the random number generator. That is not the only
* dependency between these, either, be real careful about
* reordering.
*/
init_auth();
init_util();
init_restrict();
init_mon();
init_systime();
init_timer();
init_lib();
init_random();
init_request();
init_control();
init_leap();
init_peer();
#ifdef REFCLOCK
init_refclock();
#endif
init_proto();
init_io();
init_loopfilter();
/*
* Get configuration. This (including argument list parsing) is
* done in a separate module since this will definitely be different
* for the gizmo board.
*/
getconfig(argc, argv);
initializing = 0;
/*
* Report that we're up to any trappers
*/
report_event(EVNT_SYSRESTART, (struct peer *)0);
/*
* Done all the preparation stuff, now the real thing. We block
* SIGIO and SIGALRM and check to see if either has occured.
* If not, we pause until one or the other does. We then call
* the timer processing routine and/or feed the incoming packets
* to the protocol module. Then around again.
*/
was_alarmed = 0;
rbuflist = (struct recvbuf *)0;
for (;;) {
int omask;
omask = sigblock(BLOCKSIGMASK);
if (alarm_flag) { /* alarmed? */
was_alarmed = 1;
alarm_flag = 0;
}
rbuflist = getrecvbufs(); /* get received buffers */
if (!was_alarmed && rbuflist == (struct recvbuf *)0) {
/*
* Nothing to do. Wait for something.
*/
#ifdef USESELECT
{
/*
* Unfortunately the Sequent doesn't give us
* a SIGIO ig the input file descriptors
* therefore we cheat and do a select()
* on all input fs's for unlimited time.
* select() will terminate on SIGALARM, SIGIO
* (maybe there was as TTY in the file descriptors)
* or on the reception of input (let's hope
* Sequents select() works for file descriptors)
*/
extern fd_set activefds;
extern int maxactivefd;
extern void input_handler();
fd_set rdfdes;
int nfound;
rdfdes = activefds;
nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
(fd_set *)0, (struct timeval *)0);
if (nfound > 0)
input_handler();
else
if (nfound == -1 && errno != EINTR)
{
syslog(LOG_ERR, "select() error: %m");
}
}
#else
sigpause(omask);
#endif
if (alarm_flag) { /* alarmed? */
was_alarmed = 1;
alarm_flag = 0;
}
rbuflist = getrecvbufs(); /* get received buffers */
}
(void)sigsetmask(omask);
/*
* Out here, signals are unblocked. Call timer routine
* to process expiry.
*/
if (was_alarmed) {
timer();
was_alarmed = 0;
}
/*
* Call the data procedure to handle each received
* packet.
*/
while (rbuflist != (struct recvbuf *)0) {
rbuf = rbuflist;
rbuflist = rbuf->next;
(rbuf->receiver)(rbuf);
freerecvbuf(rbuf);
}
/*
* Go around again
*/
}
}
#ifdef SIGDIE1
/*
* finish - exit gracefully
*/
void
finish()
{
struct timeval tv;
/*
* The only thing we really want to do here is make sure
* any pending time adjustment is terminated, as a bug
* preventative. Also log any useful info before exiting.
*/
tv.tv_sec = tv.tv_usec = 0;
(void) adjtime(&tv, (struct timeval *)0);
#ifdef notdef
log_exit_stats();
#endif
exit(0);
}
#endif /* SIGDIE1 */
#ifdef DEBUG
/*
* moredebug - increase debugging verbosity
*/
void
moredebug()
{
if (debug < 255) {
debug++;
syslog(LOG_DEBUG, "debug raised to %d", debug);
}
}
/*
* lessdebug - decrease debugging verbosity
*/
void
lessdebug()
{
if (debug > 0) {
debug--;
syslog(LOG_DEBUG, "debug lowered to %d", debug);
}
}
#endif /* DEBUG */