2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afs/param.h>
11 #include <afsconfig.h>
19 #include <afs/com_err.h>
20 #include <afs/cellconfig.h>
21 #include <afs/afsutil.h>
28 static afs_int32 lastTime = 0;
30 static afs_int32 GetCellInfo (cellinfoP)
31 struct afsconf_cell *cellinfoP;
33 struct afsconf_dir *conf;
34 char lcell[MAXHOSTCHARS];
37 conf = afsconf_Open (AFSDIR_SERVER_ETC_DIRPATH);
38 if (conf == 0) return AFSCONF_NOTFOUND;
39 code = afsconf_GetLocalCell (conf, lcell, sizeof(lcell));
40 if (code) return code;
41 code = afsconf_GetCellInfo (conf, lcell, 0, cellinfoP);
42 lastTime = conf->timeRead;
47 /* Check the date of the afsconf stuff and return 0 if its date is the
48 same as the last call the GetCellInfo. */
50 static int IsCellInfoNew ()
51 { struct afsconf_dir *conf;
54 /* not using cellinfo, so always return OK */
55 if (lastTime == 0) return 0;
57 conf = afsconf_Open (AFSDIR_SERVER_ETC_DIRPATH);
58 if (conf == 0) return 1; /* something's wrong */
59 new = conf->timeRead != lastTime;
64 int pid = 0; /* process id of ntpd */
69 if (pid) kill (pid, 9); /* kill off ntpd */
73 #include "AFS_component_version_number.c"
81 FILE *f; /* ntp.conf output file */
84 int local = 0; /* just use machine's local clock */
85 int precision = 0; /* precision specification */
86 int stratum = 12; /* stratum for local clock */
87 char *logfile; /* file for ntpd output streams */
88 char *ntpdPath; /* pathname of ntpd executable */
89 int nHostArgs = 0; /* number of explicit hosts */
90 char *explicitHosts[10]; /* hosts names from arglist */
94 * The following signal action for AIX is necessary so that in case of a
95 * crash (i.e. core is generated) we can include the user's data section
96 * in the core dump. Unfortunately, by default, only a partial core is
97 * generated which, in many cases, isn't too useful.
101 sigemptyset(&nsa.sa_mask);
102 nsa.sa_handler = SIG_DFL;
103 nsa.sa_flags = SA_FULLDUMP;
104 sigaction(SIGSEGV, &nsa, NULL);
109 /* Initialize dirpaths */
110 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
111 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
115 ntpdPath = AFSDIR_SERVER_NTPD_FILEPATH;
116 for (a=1; a<argc; a++) {
117 if (strcmp (argv[a], "-localclock") == 0) local = 1;
118 else if (strcmp (argv[a], "-precision") == 0) {
119 if (++a >= argc) goto usage;
120 precision = atoi(argv[a]); /* next arg is (negative) precision */
122 else if (strcmp (argv[a], "-logfile") == 0) {
123 if (++a >= argc) goto usage;
124 logfile = argv[a]; /* next arg is pathname for stdout */
125 f = fopen(logfile, "a");
127 com_err (whoami, errno, "Can't open %s as logfile", logfile);
132 else if (strcmp (argv[a], "-ntpdpath") == 0) {
133 if (++a >= argc) goto usage;
134 ntpdPath = argv[a]; /* next arg is pathname of ntpd */
135 f = fopen(ntpdPath, "r");
137 com_err (whoami, errno,
138 "Can't find ntp daemon at %s", ntpdPath);
143 else if (argv[a][0] != '-') { /* must be a hostname */
144 if (nHostArgs >= sizeof(explicitHosts)/sizeof(explicitHosts[0])) {
145 com_err (whoami, 0, "Too many hosts specified");
147 } else explicitHosts[nHostArgs++] = argv[a];
151 fprintf (stdout, "Usage: %s [-localclock] [-precision <small-negative-integer>] [-logfile <filename for ntpd's stdout/stderr] [-ntpdpath <pathname of ntpd executable (/usr/afs/bin/ntpd)>] [<host>*] [-help]\n", whoami);
156 /* setup to write to output file */
157 filename = "/tmp/ntp.conf";
158 f = fopen (filename, "w");
160 com_err (whoami, errno, "can't create output file %s", filename);
164 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
166 * NOTE: Ntpd does not know how to set kernel variables on Solaris
167 * systems, and it does not seem to be necessary on Solaris 2.6 and
171 /* first, for SUNs set tickadj and dosynctodr */
172 fprintf (f, "setdosynctodr Y\nsettickadj Y\n");
175 /* specify precision */
177 fprintf (f, "precision %d\n", precision);
180 /* then dump the appropriate type of host list */
182 if (local) { /* use the machines local clock */
183 fprintf (f, "peer\t/dev/null\tLOCL\t%d\t%d\tlocal\n",
186 if (nHostArgs) { /* use the explicitly provided list */
187 for (i=0; i<nHostArgs; i++) {
188 fprintf (f, "peer\t%s\n", explicitHosts[i]);
191 if (!(local || nHostArgs)) { /* just use CellServDB info instead */
192 struct afsconf_cell cellinfo;
194 code = GetCellInfo (&cellinfo);
196 com_err (whoami, 0, "can't get local cell info");
199 for (i=0; i<cellinfo.numServers; i++) {
200 fprintf (f, "peer\t%s\t#%s\n",
201 inet_ntoa(cellinfo.hostAddr[i].sin_addr),
202 cellinfo.hostName[i]);
206 /* all done with ntp.conf file */
207 if (fclose (f) == EOF) {
208 com_err (whoami, errno, "can't close output file %s", filename);
212 /* handle bozo kills right */
214 { struct sigaction sa;
215 bzero((char *)&sa, sizeof(sa));
216 sa.sa_handler = terminate;
217 code = sigaction (SIGTERM, &sa, NULL);
219 com_err (whoami, errno, "can't set up handler for SIGTERM");
224 /* now start ntpd with proper arguments */
228 com_err (whoami, errno, "forking for ntpd process");
231 if (pid == 0) { /* this is child */
234 afs_int32 now = time(0);
235 extern char *ctime();
236 char *nowString = ctime (&now);
238 if (logfile == 0) logfile = "/dev/null";
239 freopen (logfile, "a", stdout);
240 freopen (logfile, "a", stderr);
241 nowString[strlen(nowString)-1] = '\0'; /* punt the newline char */
242 fprintf (stdout, "Starting %s at %s with output to logfile\n",
243 ntpdPath, nowString);
247 argv[1] = "-f"; /* don't fork */
248 argv[2] = "-c"; /* read our conf file */
252 code = execve (ntpdPath, argv, envp);
253 if (code) com_err (whoami, errno, "execve of %s failed", ntpdPath);
256 else { /* this is parent */
258 int waitInterval = 0;
260 i = wait3 (&status, WNOHANG|WUNTRACED, 0);
262 (void) kill (pid, 9); /* try to kill off ntpd */
263 com_err (whoami, errno, "wait3 ing");
265 } else if (i == pid) {
266 printf ("ntpd exited status = %x (code=%d, %ssignal=%d)\n",
267 status, (status&0xffff)>>8,
268 ((status&0x80) ? "coredump, ":""), status&0x7f);
271 printf ("strange return from wait3 %d\n", i);
274 sleep (waitInterval>60 ? 60 : waitInterval++);
275 } while (!IsCellInfoNew());
277 code = kill (pid, 9); /* kill off ntpd */
278 if (code) com_err (whoami, errno, "trying to kill ntpd process");
279 else printf ("Exiting due to change in cellinfo\n");