xref: /freebsd/contrib/ntp/util/tickadj.c (revision 416ba5c74546f32a993436a99516d35008e9f384)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * tickadj - read, and possibly modify, the kernel `tick' and
3c0b746e5SOllivier Robert  *	     `tickadj' variables, as well as `dosynctodr'.  Note that
4c0b746e5SOllivier Robert  *	     this operates on the running kernel only.  I'd like to be
5c0b746e5SOllivier Robert  *	     able to read and write the binary as well, but haven't
6c0b746e5SOllivier Robert  *	     mastered this yet.
7c0b746e5SOllivier Robert  *
8c0b746e5SOllivier Robert  * HMS: The #includes here are different from those in xntpd/ntp_unixclock.c
9c0b746e5SOllivier Robert  *      These seem "worse".
10c0b746e5SOllivier Robert  */
11c0b746e5SOllivier Robert 
12c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H
13c0b746e5SOllivier Robert # include <config.h>
14c0b746e5SOllivier Robert #endif
15c0b746e5SOllivier Robert 
16224ba2bdSOllivier Robert #include "ntp_types.h"
17224ba2bdSOllivier Robert #include "l_stdlib.h"
18224ba2bdSOllivier Robert 
19c0b746e5SOllivier Robert #include <stdio.h>
20c0b746e5SOllivier Robert #ifdef HAVE_UNISTD_H
21c0b746e5SOllivier Robert # include <unistd.h>
22c0b746e5SOllivier Robert #endif /* HAVE_UNISTD_H */
23c0b746e5SOllivier Robert 
24*2b15cb3dSCy Schubert #ifdef HAVE_SYS_TIMEX_H
25c0b746e5SOllivier Robert # include <sys/timex.h>
26*2b15cb3dSCy Schubert #endif
27*2b15cb3dSCy Schubert 
28*2b15cb3dSCy Schubert #ifdef HAVE_ADJTIMEX	/* Linux */
29*2b15cb3dSCy Schubert 
30c0b746e5SOllivier Robert struct timex txc;
31c0b746e5SOllivier Robert 
32c0b746e5SOllivier Robert #if 0
33c0b746e5SOllivier Robert int
34c0b746e5SOllivier Robert main(
35c0b746e5SOllivier Robert 	int argc,
36c0b746e5SOllivier Robert 	char *argv[]
37c0b746e5SOllivier Robert 	)
38c0b746e5SOllivier Robert {
39c0b746e5SOllivier Robert 	int     c, i;
40c0b746e5SOllivier Robert 	int     quiet = 0;
41c0b746e5SOllivier Robert 	int     errflg = 0;
42c0b746e5SOllivier Robert 	char    *progname;
43c0b746e5SOllivier Robert 	extern int ntp_optind;
44c0b746e5SOllivier Robert 	extern char *ntp_optarg;
45c0b746e5SOllivier Robert 
46c0b746e5SOllivier Robert 	progname = argv[0];
47c0b746e5SOllivier Robert 	if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */
48c0b746e5SOllivier Robert 	    if ((i = atoi(argv[1])) > 0) {
49c0b746e5SOllivier Robert 		    txc.time_tick = i;
50c0b746e5SOllivier Robert 		    txc.modes = ADJ_TIMETICK;
51c0b746e5SOllivier Robert 	    } else {
52c0b746e5SOllivier Robert 		    fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
53c0b746e5SOllivier Robert 		    errflg++;
54c0b746e5SOllivier Robert 	    }
55c0b746e5SOllivier Robert 	} else {
56c0b746e5SOllivier Robert 	    while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) {
57c0b746e5SOllivier Robert 		switch (c) {
58c0b746e5SOllivier Robert 		    case 'a':
59c0b746e5SOllivier Robert 			if ((i=atoi(ntp_optarg)) > 0) {
60c0b746e5SOllivier Robert 				txc.tickadj = i;
61c0b746e5SOllivier Robert 				txc.modes |= ADJ_TICKADJ;
62c0b746e5SOllivier Robert 			} else {
63*2b15cb3dSCy Schubert 				fprintf(stderr,
64c0b746e5SOllivier Robert 					"%s: unlikely value for tickadj: %s\n",
65c0b746e5SOllivier Robert 					progname, ntp_optarg);
66c0b746e5SOllivier Robert 				errflg++;
67c0b746e5SOllivier Robert 			}
68c0b746e5SOllivier Robert 			break;
69c0b746e5SOllivier Robert 
70c0b746e5SOllivier Robert 		    case 'q':
71c0b746e5SOllivier Robert 			quiet = 1;
72c0b746e5SOllivier Robert 			break;
73c0b746e5SOllivier Robert 
74c0b746e5SOllivier Robert 		    case 't':
75c0b746e5SOllivier Robert 			if ((i=atoi(ntp_optarg)) > 0) {
76c0b746e5SOllivier Robert 				txc.time_tick = i;
77c0b746e5SOllivier Robert 				txc.modes |= ADJ_TIMETICK;
78c0b746e5SOllivier Robert 			} else {
79c0b746e5SOllivier Robert 				(void) fprintf(stderr,
80c0b746e5SOllivier Robert 				       "%s: unlikely value for tick: %s\n",
81c0b746e5SOllivier Robert 				       progname, ntp_optarg);
82c0b746e5SOllivier Robert 				errflg++;
83c0b746e5SOllivier Robert 			}
84c0b746e5SOllivier Robert 			break;
85c0b746e5SOllivier Robert 
86c0b746e5SOllivier Robert 		    default:
87c0b746e5SOllivier Robert 			fprintf(stderr,
88c0b746e5SOllivier Robert 			    "Usage: %s [tick_value]\n-or-   %s [ -q ] [ -t tick ] [ -a tickadj ]\n",
89c0b746e5SOllivier Robert 			    progname, progname);
90c0b746e5SOllivier Robert 			errflg++;
91c0b746e5SOllivier Robert 			break;
92c0b746e5SOllivier Robert 		}
93c0b746e5SOllivier Robert 	    }
94c0b746e5SOllivier Robert 	}
95c0b746e5SOllivier Robert 
96c0b746e5SOllivier Robert 	if (!errflg) {
97*2b15cb3dSCy Schubert 		if (adjtimex(&txc) < 0)
98c0b746e5SOllivier Robert 			perror("adjtimex");
99c0b746e5SOllivier Robert 		else if (!quiet)
100c0b746e5SOllivier Robert 			printf("tick     = %ld\ntick_adj = %d\n",
101c0b746e5SOllivier Robert 			    txc.time_tick, txc.tickadj);
102c0b746e5SOllivier Robert 	}
103c0b746e5SOllivier Robert 
104c0b746e5SOllivier Robert 	exit(errflg ? 1 : 0);
105c0b746e5SOllivier Robert }
106c0b746e5SOllivier Robert #else
107c0b746e5SOllivier Robert int
main(int argc,char * argv[])108c0b746e5SOllivier Robert main(
109c0b746e5SOllivier Robert 	int argc,
110c0b746e5SOllivier Robert 	char *argv[]
111c0b746e5SOllivier Robert 	)
112c0b746e5SOllivier Robert {
113c0b746e5SOllivier Robert 	if (argc > 2)
114c0b746e5SOllivier Robert 	{
115c0b746e5SOllivier Robert 		fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
116c0b746e5SOllivier Robert 		exit(-1);
117c0b746e5SOllivier Robert 	}
118c0b746e5SOllivier Robert 	else if (argc == 2)
119c0b746e5SOllivier Robert 	{
120c0b746e5SOllivier Robert #ifdef ADJ_TIMETICK
121c0b746e5SOllivier Robert 		if ( (txc.time_tick = atoi(argv[1])) < 1 )
122c0b746e5SOllivier Robert #else
123c0b746e5SOllivier Robert 		if ( (txc.tick = atoi(argv[1])) < 1 )
124c0b746e5SOllivier Robert #endif
125c0b746e5SOllivier Robert 		{
126c0b746e5SOllivier Robert 			fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
127c0b746e5SOllivier Robert 			exit(-1);
128c0b746e5SOllivier Robert 		}
129c0b746e5SOllivier Robert #ifdef ADJ_TIMETICK
130c0b746e5SOllivier Robert 		txc.modes = ADJ_TIMETICK;
131c0b746e5SOllivier Robert #else
132c0b746e5SOllivier Robert #ifdef MOD_OFFSET
133c0b746e5SOllivier Robert 		txc.modes = ADJ_TICK;
134c0b746e5SOllivier Robert #else
135c0b746e5SOllivier Robert 		txc.mode = ADJ_TICK;
136c0b746e5SOllivier Robert #endif
137c0b746e5SOllivier Robert #endif
138c0b746e5SOllivier Robert 	}
139c0b746e5SOllivier Robert 	else
140c0b746e5SOllivier Robert 	{
141c0b746e5SOllivier Robert #ifdef ADJ_TIMETICK
142c0b746e5SOllivier Robert 		txc.modes = 0;
143c0b746e5SOllivier Robert #else
144c0b746e5SOllivier Robert #ifdef MOD_OFFSET
145c0b746e5SOllivier Robert 		txc.modes = 0;
146c0b746e5SOllivier Robert #else
147c0b746e5SOllivier Robert 		txc.mode = 0;
148c0b746e5SOllivier Robert #endif
149c0b746e5SOllivier Robert #endif
150c0b746e5SOllivier Robert 	}
151c0b746e5SOllivier Robert 
152*2b15cb3dSCy Schubert 	if (adjtimex(&txc) < 0)
153c0b746e5SOllivier Robert 	{
154c0b746e5SOllivier Robert 		perror("adjtimex");
155c0b746e5SOllivier Robert 	}
156c0b746e5SOllivier Robert 	else
157c0b746e5SOllivier Robert 	{
158c0b746e5SOllivier Robert #ifdef ADJ_TIMETICK
159c0b746e5SOllivier Robert 		printf("tick     = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
160c0b746e5SOllivier Robert #else
161c0b746e5SOllivier Robert 		printf("tick = %ld\n", txc.tick);
162c0b746e5SOllivier Robert #endif
163c0b746e5SOllivier Robert 	}
164c0b746e5SOllivier Robert 
165c0b746e5SOllivier Robert 	exit(0);
166c0b746e5SOllivier Robert }
167c0b746e5SOllivier Robert #endif
168c0b746e5SOllivier Robert 
169c0b746e5SOllivier Robert #else	/* not Linux... kmem tweaking: */
170c0b746e5SOllivier Robert 
171c0b746e5SOllivier Robert #ifdef HAVE_SYS_FILE_H
172c0b746e5SOllivier Robert # include <sys/file.h>
173c0b746e5SOllivier Robert #endif
174c0b746e5SOllivier Robert #include <sys/stat.h>
175c0b746e5SOllivier Robert 
176c0b746e5SOllivier Robert #ifdef HAVE_SYS_PARAM_H
177c0b746e5SOllivier Robert # include <sys/param.h>
178c0b746e5SOllivier Robert #endif
179c0b746e5SOllivier Robert 
180c0b746e5SOllivier Robert #ifdef NLIST_STRUCT
181c0b746e5SOllivier Robert # include <nlist.h>
182c0b746e5SOllivier Robert #else /* not NLIST_STRUCT */ /* was defined(SYS_AUX3) || defined(SYS_AUX2) */
183c0b746e5SOllivier Robert # include <sys/resource.h>
184c0b746e5SOllivier Robert # include <sys/file.h>
185c0b746e5SOllivier Robert # include <a.out.h>
186*2b15cb3dSCy Schubert # ifdef HAVE_SYS_VAR_H
187c0b746e5SOllivier Robert #  include <sys/var.h>
188c0b746e5SOllivier Robert # endif
189*2b15cb3dSCy Schubert #endif
190c0b746e5SOllivier Robert 
191c0b746e5SOllivier Robert #include "ntp_stdlib.h"
192*2b15cb3dSCy Schubert #include "ntp_io.h"
193c0b746e5SOllivier Robert 
194c0b746e5SOllivier Robert #ifdef hz /* Was: RS6000 */
195c0b746e5SOllivier Robert # undef hz
196c0b746e5SOllivier Robert #endif /* hz */
197c0b746e5SOllivier Robert 
198c0b746e5SOllivier Robert #ifdef HAVE_KVM_OPEN
199c0b746e5SOllivier Robert # include <kvm.h>
200c0b746e5SOllivier Robert #endif
201c0b746e5SOllivier Robert 
202c0b746e5SOllivier Robert #ifdef SYS_VXWORKS
203c0b746e5SOllivier Robert /* vxWorks needs mode flag -casey*/
204c0b746e5SOllivier Robert #define open(name, flags)   open(name, flags, 0777)
205c0b746e5SOllivier Robert #endif
206c0b746e5SOllivier Robert 
207c0b746e5SOllivier Robert #ifndef L_SET	/* Was: defined(SYS_PTX) || defined(SYS_IX86OSF1) */
208c0b746e5SOllivier Robert # define L_SET SEEK_SET
209c0b746e5SOllivier Robert #endif
210c0b746e5SOllivier Robert 
211c0b746e5SOllivier Robert #ifndef HZ
212c0b746e5SOllivier Robert # define HZ	DEFAULT_HZ
213c0b746e5SOllivier Robert #endif
214c0b746e5SOllivier Robert 
215c0b746e5SOllivier Robert #define	KMEM	"/dev/kmem"
216c0b746e5SOllivier Robert #define	STREQ(a, b)	(*(a) == *(b) && strcmp((a), (b)) == 0)
217c0b746e5SOllivier Robert 
218c0b746e5SOllivier Robert char *progname;
219c0b746e5SOllivier Robert 
220c0b746e5SOllivier Robert int dokmem = 1;
221c0b746e5SOllivier Robert int writetickadj = 0;
222c0b746e5SOllivier Robert int writeopttickadj = 0;
223c0b746e5SOllivier Robert int unsetdosync = 0;
224c0b746e5SOllivier Robert int writetick = 0;
225c0b746e5SOllivier Robert int quiet = 0;
226c0b746e5SOllivier Robert int setnoprintf = 0;
227c0b746e5SOllivier Robert 
228c0b746e5SOllivier Robert const char *kmem = KMEM;
229c0b746e5SOllivier Robert const char *file = NULL;
230c0b746e5SOllivier Robert int   fd  = -1;
231c0b746e5SOllivier Robert 
232*2b15cb3dSCy Schubert static	void	getoffsets	(off_t *, off_t *, off_t *, off_t *);
233*2b15cb3dSCy Schubert static	int	openfile	(const char *, int);
234*2b15cb3dSCy Schubert static	void	writevar	(int, off_t, int);
235*2b15cb3dSCy Schubert static	void	readvar		(int, off_t, int *);
236c0b746e5SOllivier Robert 
237c0b746e5SOllivier Robert /*
238c0b746e5SOllivier Robert  * main - parse arguments and handle options
239c0b746e5SOllivier Robert  */
240c0b746e5SOllivier Robert int
main(int argc,char * argv[])241c0b746e5SOllivier Robert main(
242c0b746e5SOllivier Robert 	int argc,
243c0b746e5SOllivier Robert 	char *argv[]
244c0b746e5SOllivier Robert 	)
245c0b746e5SOllivier Robert {
246c0b746e5SOllivier Robert 	int c;
247c0b746e5SOllivier Robert 	int errflg = 0;
248c0b746e5SOllivier Robert 	off_t tickadj_offset;
249c0b746e5SOllivier Robert 	off_t tick_offset;
250c0b746e5SOllivier Robert 	off_t dosync_offset;
251c0b746e5SOllivier Robert 	off_t noprintf_offset;
252c0b746e5SOllivier Robert 	int tickadj, ktickadj;	/* HMS: Why isn't this u_long? */
253c0b746e5SOllivier Robert 	int tick, ktick;	/* HMS: Why isn't this u_long? */
254c0b746e5SOllivier Robert 	int dosynctodr;
255c0b746e5SOllivier Robert 	int noprintf;
256c0b746e5SOllivier Robert 	int hz;
257c0b746e5SOllivier Robert 	int hz_int, hz_hundredths;
258c0b746e5SOllivier Robert 	int recommend_tickadj;
259c0b746e5SOllivier Robert 	long tmp;
260c0b746e5SOllivier Robert 
261*2b15cb3dSCy Schubert 	init_lib();
262*2b15cb3dSCy Schubert 
263c0b746e5SOllivier Robert 	progname = argv[0];
264c0b746e5SOllivier Robert 	while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF)
265c0b746e5SOllivier Robert 	{
266c0b746e5SOllivier Robert 		switch (c)
267c0b746e5SOllivier Robert 		{
268c0b746e5SOllivier Robert 		    case 'a':
269c0b746e5SOllivier Robert 			writetickadj = atoi(ntp_optarg);
270c0b746e5SOllivier Robert 			if (writetickadj <= 0)
271c0b746e5SOllivier Robert 			{
272c0b746e5SOllivier Robert 				(void) fprintf(stderr,
273c0b746e5SOllivier Robert 					       "%s: unlikely value for tickadj: %s\n",
274c0b746e5SOllivier Robert 					       progname, ntp_optarg);
275c0b746e5SOllivier Robert 				errflg++;
276c0b746e5SOllivier Robert 			}
277c0b746e5SOllivier Robert 
278c0b746e5SOllivier Robert #if defined SCO5_CLOCK
279c0b746e5SOllivier Robert 			if (writetickadj % HZ)
280c0b746e5SOllivier Robert 			{
281c0b746e5SOllivier Robert 				writetickadj = (writetickadj / HZ) * HZ;
282c0b746e5SOllivier Robert 				(void) fprintf(stderr,
283c0b746e5SOllivier Robert 					       "tickadj truncated to: %d\n", writetickadj);
284c0b746e5SOllivier Robert 			}
285c0b746e5SOllivier Robert #endif /* SCO5_CLOCK */
286c0b746e5SOllivier Robert 
287c0b746e5SOllivier Robert 			break;
288c0b746e5SOllivier Robert 		    case 'A':
289c0b746e5SOllivier Robert 			writeopttickadj = 1;
290c0b746e5SOllivier Robert 			break;
291c0b746e5SOllivier Robert 		    case 'd':
292c0b746e5SOllivier Robert 			++debug;
293c0b746e5SOllivier Robert 			break;
294c0b746e5SOllivier Robert 		    case 'k':
295c0b746e5SOllivier Robert 			dokmem = 1;
296c0b746e5SOllivier Robert 			break;
297c0b746e5SOllivier Robert 		    case 'p':
298c0b746e5SOllivier Robert 			setnoprintf = 1;
299c0b746e5SOllivier Robert 			break;
300c0b746e5SOllivier Robert 		    case 'q':
301c0b746e5SOllivier Robert 			quiet = 1;
302c0b746e5SOllivier Robert 			break;
303c0b746e5SOllivier Robert 		    case 's':
304c0b746e5SOllivier Robert 			unsetdosync = 1;
305c0b746e5SOllivier Robert 			break;
306c0b746e5SOllivier Robert 		    case 't':
307c0b746e5SOllivier Robert 			writetick = atoi(ntp_optarg);
308c0b746e5SOllivier Robert 			if (writetick <= 0)
309c0b746e5SOllivier Robert 			{
310c0b746e5SOllivier Robert 				(void) fprintf(stderr,
311c0b746e5SOllivier Robert 					       "%s: unlikely value for tick: %s\n",
312c0b746e5SOllivier Robert 					       progname, ntp_optarg);
313c0b746e5SOllivier Robert 				errflg++;
314c0b746e5SOllivier Robert 			}
315c0b746e5SOllivier Robert 			break;
316c0b746e5SOllivier Robert 		    default:
317c0b746e5SOllivier Robert 			errflg++;
318c0b746e5SOllivier Robert 			break;
319c0b746e5SOllivier Robert 		}
320c0b746e5SOllivier Robert 	}
321c0b746e5SOllivier Robert 	if (errflg || ntp_optind != argc)
322c0b746e5SOllivier Robert 	{
323c0b746e5SOllivier Robert 		(void) fprintf(stderr,
324c0b746e5SOllivier Robert 			       "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname);
325c0b746e5SOllivier Robert 		exit(2);
326c0b746e5SOllivier Robert 	}
327c0b746e5SOllivier Robert 
328c0b746e5SOllivier Robert 	getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset);
329c0b746e5SOllivier Robert 
330c0b746e5SOllivier Robert 	if (debug)
331c0b746e5SOllivier Robert 	{
332c0b746e5SOllivier Robert 		(void) printf("tick offset = %lu\n", (unsigned long)tick_offset);
333c0b746e5SOllivier Robert 		(void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset);
334c0b746e5SOllivier Robert 		(void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset);
335c0b746e5SOllivier Robert 		(void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset);
336c0b746e5SOllivier Robert 	}
337c0b746e5SOllivier Robert 
338c0b746e5SOllivier Robert 	if (writetick && (tick_offset == 0))
339c0b746e5SOllivier Robert 	{
340c0b746e5SOllivier Robert 		(void) fprintf(stderr,
341c0b746e5SOllivier Robert 			       "No tick kernel variable\n");
342c0b746e5SOllivier Robert 		errflg++;
343c0b746e5SOllivier Robert 	}
344c0b746e5SOllivier Robert 
345c0b746e5SOllivier Robert 	if (writeopttickadj && (tickadj_offset == 0))
346c0b746e5SOllivier Robert 	{
347c0b746e5SOllivier Robert 		(void) fprintf(stderr,
348c0b746e5SOllivier Robert 			       "No tickadj kernel variable\n");
349c0b746e5SOllivier Robert 		errflg++;
350c0b746e5SOllivier Robert 	}
351c0b746e5SOllivier Robert 
352c0b746e5SOllivier Robert 	if (unsetdosync && (dosync_offset == 0))
353c0b746e5SOllivier Robert 	{
354c0b746e5SOllivier Robert 		(void) fprintf(stderr,
355c0b746e5SOllivier Robert 			       "No dosynctodr kernel variable\n");
356c0b746e5SOllivier Robert 		errflg++;
357c0b746e5SOllivier Robert 	}
358c0b746e5SOllivier Robert 
359c0b746e5SOllivier Robert 	if (setnoprintf && (noprintf_offset == 0))
360c0b746e5SOllivier Robert 	{
361c0b746e5SOllivier Robert 		(void) fprintf(stderr,
362c0b746e5SOllivier Robert 			       "No noprintf kernel variable\n");
363c0b746e5SOllivier Robert 		errflg++;
364c0b746e5SOllivier Robert 	}
365c0b746e5SOllivier Robert 
366c0b746e5SOllivier Robert 	if (tick_offset != 0)
367c0b746e5SOllivier Robert 	{
368c0b746e5SOllivier Robert 		readvar(fd, tick_offset, &tick);
369c0b746e5SOllivier Robert #if defined(TICK_NANO) && defined(K_TICK_NAME)
370c0b746e5SOllivier Robert 		if (!quiet)
371c0b746e5SOllivier Robert 		    (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick);
372c0b746e5SOllivier Robert #endif /* TICK_NANO && K_TICK_NAME */
373c0b746e5SOllivier Robert 
374c0b746e5SOllivier Robert #ifdef TICK_NANO
375c0b746e5SOllivier Robert 		tick /= 1000;
376c0b746e5SOllivier Robert #endif
377c0b746e5SOllivier Robert 	}
378c0b746e5SOllivier Robert 	else
379c0b746e5SOllivier Robert 	{
380c0b746e5SOllivier Robert 		tick = 0;
381c0b746e5SOllivier Robert 	}
382c0b746e5SOllivier Robert 
383c0b746e5SOllivier Robert 	if (tickadj_offset != 0)
384c0b746e5SOllivier Robert 	{
385c0b746e5SOllivier Robert 		readvar(fd, tickadj_offset, &tickadj);
386c0b746e5SOllivier Robert 
387c0b746e5SOllivier Robert #ifdef SCO5_CLOCK
388c0b746e5SOllivier Robert 		/* scale from nsec/sec to usec/tick */
389c0b746e5SOllivier Robert 		tickadj /= (1000L * HZ);
390c0b746e5SOllivier Robert #endif /*SCO5_CLOCK */
391c0b746e5SOllivier Robert 
392c0b746e5SOllivier Robert #if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME)
393c0b746e5SOllivier Robert 		if (!quiet)
394c0b746e5SOllivier Robert 		    (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj);
395c0b746e5SOllivier Robert #endif /* TICKADJ_NANO && K_TICKADJ_NAME */
396c0b746e5SOllivier Robert 
397c0b746e5SOllivier Robert #ifdef TICKADJ_NANO
398c0b746e5SOllivier Robert 		tickadj += 999;
399c0b746e5SOllivier Robert 		tickadj /= 1000;
400c0b746e5SOllivier Robert #endif
401c0b746e5SOllivier Robert 	}
402c0b746e5SOllivier Robert 	else
403c0b746e5SOllivier Robert 	{
404c0b746e5SOllivier Robert 		tickadj = 0;
405c0b746e5SOllivier Robert 	}
406c0b746e5SOllivier Robert 
407c0b746e5SOllivier Robert 	if (dosync_offset != 0)
408c0b746e5SOllivier Robert 	{
409c0b746e5SOllivier Robert 		readvar(fd, dosync_offset, &dosynctodr);
410c0b746e5SOllivier Robert 	}
411c0b746e5SOllivier Robert 
412c0b746e5SOllivier Robert 	if (noprintf_offset != 0)
413c0b746e5SOllivier Robert 	{
414c0b746e5SOllivier Robert 		readvar(fd, noprintf_offset, &noprintf);
415c0b746e5SOllivier Robert 	}
416c0b746e5SOllivier Robert 
417c0b746e5SOllivier Robert 	(void) close(fd);
418c0b746e5SOllivier Robert 
419c0b746e5SOllivier Robert 	if (unsetdosync && dosync_offset == 0)
420c0b746e5SOllivier Robert 	{
421c0b746e5SOllivier Robert 		(void) fprintf(stderr,
422c0b746e5SOllivier Robert 			       "%s: can't find %s in namelist\n",
423c0b746e5SOllivier Robert 			       progname,
424c0b746e5SOllivier Robert #ifdef K_DOSYNCTODR_NAME
425c0b746e5SOllivier Robert 			       K_DOSYNCTODR_NAME
426c0b746e5SOllivier Robert #else /* not K_DOSYNCTODR_NAME */
427c0b746e5SOllivier Robert 			       "dosynctodr"
428c0b746e5SOllivier Robert #endif /* not K_DOSYNCTODR_NAME */
429c0b746e5SOllivier Robert 			       );
430c0b746e5SOllivier Robert 		exit(1);
431c0b746e5SOllivier Robert 	}
432c0b746e5SOllivier Robert 
433c0b746e5SOllivier Robert 	hz = HZ;
434c0b746e5SOllivier Robert #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
435c0b746e5SOllivier Robert 	hz = (int) sysconf (_SC_CLK_TCK);
436c0b746e5SOllivier Robert #endif /* not HAVE_SYSCONF && _SC_CLK_TCK */
437c0b746e5SOllivier Robert #ifdef OVERRIDE_HZ
438c0b746e5SOllivier Robert 	hz = DEFAULT_HZ;
439c0b746e5SOllivier Robert #endif
440c0b746e5SOllivier Robert 	ktick = tick;
441c0b746e5SOllivier Robert #ifdef PRESET_TICK
442c0b746e5SOllivier Robert 	tick = PRESET_TICK;
443c0b746e5SOllivier Robert #endif /* PRESET_TICK */
444c0b746e5SOllivier Robert #ifdef TICKADJ_NANO
445c0b746e5SOllivier Robert 	tickadj /= 1000;
446c0b746e5SOllivier Robert 	if (tickadj == 0)
447c0b746e5SOllivier Robert 	    tickadj = 1;
448c0b746e5SOllivier Robert #endif
449c0b746e5SOllivier Robert 	ktickadj = tickadj;
450c0b746e5SOllivier Robert #ifdef PRESET_TICKADJ
451c0b746e5SOllivier Robert 	tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1;
452c0b746e5SOllivier Robert #endif /* PRESET_TICKADJ */
453c0b746e5SOllivier Robert 
454c0b746e5SOllivier Robert 	if (!quiet)
455c0b746e5SOllivier Robert 	{
456c0b746e5SOllivier Robert 		if (tick_offset != 0)
457c0b746e5SOllivier Robert 		{
458c0b746e5SOllivier Robert 			(void) printf("KERNEL tick = %d usec (from %s kernel variable)\n",
459c0b746e5SOllivier Robert 				      ktick,
460c0b746e5SOllivier Robert #ifdef K_TICK_NAME
461c0b746e5SOllivier Robert 				      K_TICK_NAME
462c0b746e5SOllivier Robert #else
463c0b746e5SOllivier Robert 				      "<this can't happen>"
464c0b746e5SOllivier Robert #endif
465c0b746e5SOllivier Robert 				      );
466c0b746e5SOllivier Robert 		}
467c0b746e5SOllivier Robert #ifdef PRESET_TICK
468c0b746e5SOllivier Robert 		(void) printf("PRESET tick = %d usec\n", tick);
469c0b746e5SOllivier Robert #endif /* PRESET_TICK */
470c0b746e5SOllivier Robert 		if (tickadj_offset != 0)
471c0b746e5SOllivier Robert 		{
472c0b746e5SOllivier Robert 			(void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n",
473c0b746e5SOllivier Robert 				      ktickadj,
474c0b746e5SOllivier Robert #ifdef K_TICKADJ_NAME
475c0b746e5SOllivier Robert 				      K_TICKADJ_NAME
476c0b746e5SOllivier Robert #else
477c0b746e5SOllivier Robert 				      "<this can't happen>"
478c0b746e5SOllivier Robert #endif
479c0b746e5SOllivier Robert 				      );
480c0b746e5SOllivier Robert 		}
481c0b746e5SOllivier Robert #ifdef PRESET_TICKADJ
482c0b746e5SOllivier Robert 		(void) printf("PRESET tickadj = %d usec\n", tickadj);
483c0b746e5SOllivier Robert #endif /* PRESET_TICKADJ */
484c0b746e5SOllivier Robert 		if (dosync_offset != 0)
485c0b746e5SOllivier Robert 		{
486c0b746e5SOllivier Robert 			(void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off");
487c0b746e5SOllivier Robert 		}
488c0b746e5SOllivier Robert 		if (noprintf_offset != 0)
489c0b746e5SOllivier Robert 		{
490c0b746e5SOllivier Robert 			(void) printf("kernel level printf's: %s\n",
491c0b746e5SOllivier Robert 				      noprintf ? "off" : "on");
492c0b746e5SOllivier Robert 		}
493c0b746e5SOllivier Robert 	}
494c0b746e5SOllivier Robert 
495c0b746e5SOllivier Robert 	if (tick <= 0)
496c0b746e5SOllivier Robert 	{
497c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: the value of tick is silly!\n",
498c0b746e5SOllivier Robert 			       progname);
499c0b746e5SOllivier Robert 		exit(1);
500c0b746e5SOllivier Robert 	}
501c0b746e5SOllivier Robert 
502c0b746e5SOllivier Robert 	hz_int = (int)(1000000L / (long)tick);
503c0b746e5SOllivier Robert 	hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L));
504c0b746e5SOllivier Robert 	if (!quiet)
505c0b746e5SOllivier Robert 	{
506c0b746e5SOllivier Robert 		(void) printf("KERNEL hz = %d\n", hz);
507c0b746e5SOllivier Robert 		(void) printf("calculated hz = %d.%02d Hz\n", hz_int,
508c0b746e5SOllivier Robert 			      hz_hundredths);
509c0b746e5SOllivier Robert 	}
510c0b746e5SOllivier Robert 
511c0b746e5SOllivier Robert #if defined SCO5_CLOCK
512c0b746e5SOllivier Robert 	recommend_tickadj = 100;
513c0b746e5SOllivier Robert #else /* SCO5_CLOCK */
514c0b746e5SOllivier Robert 	tmp = (long) tick * 500L;
515c0b746e5SOllivier Robert 	recommend_tickadj = (int)(tmp / 1000000L);
516c0b746e5SOllivier Robert 	if (tmp % 1000000L > 0)
517c0b746e5SOllivier Robert 	{
518c0b746e5SOllivier Robert 		recommend_tickadj++;
519c0b746e5SOllivier Robert 	}
520c0b746e5SOllivier Robert 
521c0b746e5SOllivier Robert #ifdef MIN_REC_TICKADJ
522c0b746e5SOllivier Robert 	if (recommend_tickadj < MIN_REC_TICKADJ)
523c0b746e5SOllivier Robert 	{
524c0b746e5SOllivier Robert 		recommend_tickadj = MIN_REC_TICKADJ;
525c0b746e5SOllivier Robert 	}
526c0b746e5SOllivier Robert #endif /* MIN_REC_TICKADJ */
527c0b746e5SOllivier Robert #endif /* SCO5_CLOCK */
528c0b746e5SOllivier Robert 
529c0b746e5SOllivier Robert 
530c0b746e5SOllivier Robert 	if ((!quiet) && (tickadj_offset != 0))
531c0b746e5SOllivier Robert 	{
532c0b746e5SOllivier Robert 		(void) printf("recommended value of tickadj = %d us\n",
533c0b746e5SOllivier Robert 			      recommend_tickadj);
534c0b746e5SOllivier Robert 	}
535c0b746e5SOllivier Robert 
536c0b746e5SOllivier Robert 	if (   writetickadj == 0
537c0b746e5SOllivier Robert 	       && !writeopttickadj
538c0b746e5SOllivier Robert 	       && !unsetdosync
539c0b746e5SOllivier Robert 	       && writetick == 0
540c0b746e5SOllivier Robert 	       && !setnoprintf)
541c0b746e5SOllivier Robert 	{
542c0b746e5SOllivier Robert 		exit(errflg ? 1 : 0);
543c0b746e5SOllivier Robert 	}
544c0b746e5SOllivier Robert 
545c0b746e5SOllivier Robert 	if (writetickadj == 0 && writeopttickadj)
546c0b746e5SOllivier Robert 	{
547c0b746e5SOllivier Robert 		writetickadj = recommend_tickadj;
548c0b746e5SOllivier Robert 	}
549c0b746e5SOllivier Robert 
550c0b746e5SOllivier Robert 	fd = openfile(file, O_WRONLY);
551c0b746e5SOllivier Robert 
552c0b746e5SOllivier Robert 	if (setnoprintf && (noprintf_offset != 0))
553c0b746e5SOllivier Robert 	{
554c0b746e5SOllivier Robert 		if (!quiet)
555c0b746e5SOllivier Robert 		{
556c0b746e5SOllivier Robert 			(void) fprintf(stderr, "setting noprintf: ");
557c0b746e5SOllivier Robert 			(void) fflush(stderr);
558c0b746e5SOllivier Robert 		}
559c0b746e5SOllivier Robert 		writevar(fd, noprintf_offset, 1);
560c0b746e5SOllivier Robert 		if (!quiet)
561c0b746e5SOllivier Robert 		{
562c0b746e5SOllivier Robert 			(void) fprintf(stderr, "done!\n");
563c0b746e5SOllivier Robert 		}
564c0b746e5SOllivier Robert 	}
565c0b746e5SOllivier Robert 
566c0b746e5SOllivier Robert 	if ((writetick > 0) && (tick_offset != 0))
567c0b746e5SOllivier Robert 	{
568c0b746e5SOllivier Robert 		if (!quiet)
569c0b746e5SOllivier Robert 		{
570c0b746e5SOllivier Robert 			(void) fprintf(stderr, "writing tick, value %d: ",
571c0b746e5SOllivier Robert 				       writetick);
572c0b746e5SOllivier Robert 			(void) fflush(stderr);
573c0b746e5SOllivier Robert 		}
574c0b746e5SOllivier Robert 		writevar(fd, tick_offset, writetick);
575c0b746e5SOllivier Robert 		if (!quiet)
576c0b746e5SOllivier Robert 		{
577c0b746e5SOllivier Robert 			(void) fprintf(stderr, "done!\n");
578c0b746e5SOllivier Robert 		}
579c0b746e5SOllivier Robert 	}
580c0b746e5SOllivier Robert 
581c0b746e5SOllivier Robert 	if ((writetickadj > 0) && (tickadj_offset != 0))
582c0b746e5SOllivier Robert 	{
583c0b746e5SOllivier Robert 		if (!quiet)
584c0b746e5SOllivier Robert 		{
585c0b746e5SOllivier Robert 			(void) fprintf(stderr, "writing tickadj, value %d: ",
586c0b746e5SOllivier Robert 				       writetickadj);
587c0b746e5SOllivier Robert 			(void) fflush(stderr);
588c0b746e5SOllivier Robert 		}
589c0b746e5SOllivier Robert 
590c0b746e5SOllivier Robert #ifdef SCO5_CLOCK
591c0b746e5SOllivier Robert 		/* scale from usec/tick to nsec/sec */
592c0b746e5SOllivier Robert 		writetickadj *= (1000L * HZ);
593c0b746e5SOllivier Robert #endif /* SCO5_CLOCK */
594c0b746e5SOllivier Robert 
595c0b746e5SOllivier Robert 		writevar(fd, tickadj_offset, writetickadj);
596c0b746e5SOllivier Robert 		if (!quiet)
597c0b746e5SOllivier Robert 		{
598c0b746e5SOllivier Robert 			(void) fprintf(stderr, "done!\n");
599c0b746e5SOllivier Robert 		}
600c0b746e5SOllivier Robert 	}
601c0b746e5SOllivier Robert 
602c0b746e5SOllivier Robert 	if (unsetdosync && (dosync_offset != 0))
603c0b746e5SOllivier Robert 	{
604c0b746e5SOllivier Robert 		if (!quiet)
605c0b746e5SOllivier Robert 		{
606c0b746e5SOllivier Robert 			(void) fprintf(stderr, "zeroing dosynctodr: ");
607c0b746e5SOllivier Robert 			(void) fflush(stderr);
608c0b746e5SOllivier Robert 		}
609c0b746e5SOllivier Robert 		writevar(fd, dosync_offset, 0);
610c0b746e5SOllivier Robert 		if (!quiet)
611c0b746e5SOllivier Robert 		{
612c0b746e5SOllivier Robert 			(void) fprintf(stderr, "done!\n");
613c0b746e5SOllivier Robert 		}
614c0b746e5SOllivier Robert 	}
615c0b746e5SOllivier Robert 	(void) close(fd);
616c0b746e5SOllivier Robert 	return(errflg ? 1 : 0);
617c0b746e5SOllivier Robert }
618c0b746e5SOllivier Robert 
619c0b746e5SOllivier Robert /*
620c0b746e5SOllivier Robert  * getoffsets - read the magic offsets from the specified file
621c0b746e5SOllivier Robert  */
622c0b746e5SOllivier Robert static void
getoffsets(off_t * tick_off,off_t * tickadj_off,off_t * dosync_off,off_t * noprintf_off)623c0b746e5SOllivier Robert getoffsets(
624c0b746e5SOllivier Robert 	off_t *tick_off,
625c0b746e5SOllivier Robert 	off_t *tickadj_off,
626c0b746e5SOllivier Robert 	off_t *dosync_off,
627c0b746e5SOllivier Robert 	off_t *noprintf_off
628c0b746e5SOllivier Robert 	)
629c0b746e5SOllivier Robert {
630c0b746e5SOllivier Robert 
631c0b746e5SOllivier Robert #ifndef NOKMEM
632c0b746e5SOllivier Robert # ifndef HAVE_KVM_OPEN
633c0b746e5SOllivier Robert 	const char **kname;
634c0b746e5SOllivier Robert # endif
635c0b746e5SOllivier Robert #endif
636c0b746e5SOllivier Robert 
637c0b746e5SOllivier Robert #ifndef NOKMEM
638c0b746e5SOllivier Robert # ifdef NLIST_NAME_UNION
639c0b746e5SOllivier Robert #  define NL_B {{
640c0b746e5SOllivier Robert #  define NL_E }}
641c0b746e5SOllivier Robert # else
642c0b746e5SOllivier Robert #  define NL_B {
643c0b746e5SOllivier Robert #  define NL_E }
644c0b746e5SOllivier Robert # endif
645c0b746e5SOllivier Robert #endif
646c0b746e5SOllivier Robert 
647c0b746e5SOllivier Robert #define K_FILLER_NAME "DavidLetterman"
648c0b746e5SOllivier Robert 
649c0b746e5SOllivier Robert #ifdef NLIST_EXTRA_INDIRECTION
650c0b746e5SOllivier Robert 	int i;
651c0b746e5SOllivier Robert #endif
652c0b746e5SOllivier Robert 
653c0b746e5SOllivier Robert #ifndef NOKMEM
654c0b746e5SOllivier Robert 	static struct nlist nl[] =
655c0b746e5SOllivier Robert 	{
656c0b746e5SOllivier Robert 		NL_B
657c0b746e5SOllivier Robert #ifdef K_TICKADJ_NAME
658c0b746e5SOllivier Robert #define N_TICKADJ	0
659c0b746e5SOllivier Robert 		K_TICKADJ_NAME
660c0b746e5SOllivier Robert #else
661c0b746e5SOllivier Robert 		K_FILLER_NAME
662c0b746e5SOllivier Robert #endif
663c0b746e5SOllivier Robert 		NL_E,
664c0b746e5SOllivier Robert 		NL_B
665c0b746e5SOllivier Robert #ifdef K_TICK_NAME
666c0b746e5SOllivier Robert #define N_TICK		1
667c0b746e5SOllivier Robert 		K_TICK_NAME
668c0b746e5SOllivier Robert #else
669c0b746e5SOllivier Robert 		K_FILLER_NAME
670c0b746e5SOllivier Robert #endif
671c0b746e5SOllivier Robert 		NL_E,
672c0b746e5SOllivier Robert 		NL_B
673c0b746e5SOllivier Robert #ifdef K_DOSYNCTODR_NAME
674c0b746e5SOllivier Robert #define N_DOSYNC	2
675c0b746e5SOllivier Robert 		K_DOSYNCTODR_NAME
676c0b746e5SOllivier Robert #else
677c0b746e5SOllivier Robert 		K_FILLER_NAME
678c0b746e5SOllivier Robert #endif
679c0b746e5SOllivier Robert 		NL_E,
680c0b746e5SOllivier Robert 		NL_B
681c0b746e5SOllivier Robert #ifdef K_NOPRINTF_NAME
682c0b746e5SOllivier Robert #define N_NOPRINTF	3
683c0b746e5SOllivier Robert 		K_NOPRINTF_NAME
684c0b746e5SOllivier Robert #else
685c0b746e5SOllivier Robert 		K_FILLER_NAME
686c0b746e5SOllivier Robert #endif
687c0b746e5SOllivier Robert 		NL_E,
688c0b746e5SOllivier Robert 		NL_B "" NL_E,
689c0b746e5SOllivier Robert 	};
690c0b746e5SOllivier Robert 
691c0b746e5SOllivier Robert #ifndef HAVE_KVM_OPEN
692c0b746e5SOllivier Robert 	static const char *kernels[] =
693c0b746e5SOllivier Robert 	{
694c0b746e5SOllivier Robert #ifdef HAVE_GETBOOTFILE
695c0b746e5SOllivier Robert 		NULL,			/* *** SEE BELOW! *** */
696c0b746e5SOllivier Robert #endif
697c0b746e5SOllivier Robert 		"/kernel/unix",
698c0b746e5SOllivier Robert 		"/kernel",
699c0b746e5SOllivier Robert 		"/vmunix",
700c0b746e5SOllivier Robert 		"/unix",
701c0b746e5SOllivier Robert 		"/mach",
702c0b746e5SOllivier Robert 		"/hp-ux",
703c0b746e5SOllivier Robert 		"/386bsd",
704c0b746e5SOllivier Robert 		"/netbsd",
705c0b746e5SOllivier Robert 		"/stand/vmunix",
706c0b746e5SOllivier Robert 		"/bsd",
707c0b746e5SOllivier Robert 		NULL
708c0b746e5SOllivier Robert 	};
709c0b746e5SOllivier Robert #endif /* not HAVE_KVM_OPEN */
710c0b746e5SOllivier Robert 
711c0b746e5SOllivier Robert #ifdef HAVE_KVM_OPEN
712c0b746e5SOllivier Robert 	/*
713c0b746e5SOllivier Robert 	 * Solaris > 2.5 doesn't have a kernel file.  Use the kvm_* interface
714c0b746e5SOllivier Robert 	 * to read the kernel name list. -- stolcke 3/4/96
715c0b746e5SOllivier Robert 	 */
716c0b746e5SOllivier Robert 	kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname);
717c0b746e5SOllivier Robert 
718c0b746e5SOllivier Robert 	if (kvm_handle == NULL)
719c0b746e5SOllivier Robert 	{
720c0b746e5SOllivier Robert 		(void) fprintf(stderr,
721c0b746e5SOllivier Robert 			       "%s: kvm_open failed\n",
722c0b746e5SOllivier Robert 			       progname);
723c0b746e5SOllivier Robert 		exit(1);
724c0b746e5SOllivier Robert 	}
725c0b746e5SOllivier Robert 	if (kvm_nlist(kvm_handle, nl) == -1)
726c0b746e5SOllivier Robert 	{
727c0b746e5SOllivier Robert 		(void) fprintf(stderr,
728c0b746e5SOllivier Robert 			       "%s: kvm_nlist failed\n",
729c0b746e5SOllivier Robert 			       progname);
730c0b746e5SOllivier Robert 		exit(1);
731c0b746e5SOllivier Robert 	}
732c0b746e5SOllivier Robert 	kvm_close(kvm_handle);
733c0b746e5SOllivier Robert #else /* not HAVE_KVM_OPEN */
734c0b746e5SOllivier Robert #ifdef HAVE_GETBOOTFILE		/* *** SEE HERE! *** */
735c0b746e5SOllivier Robert 	if (kernels[0] == NULL)
736c0b746e5SOllivier Robert 	{
737c0b746e5SOllivier Robert 		char * cp = (char *)getbootfile();
738c0b746e5SOllivier Robert 
739c0b746e5SOllivier Robert 		if (cp)
740c0b746e5SOllivier Robert 		{
741c0b746e5SOllivier Robert 			kernels[0] = cp;
742c0b746e5SOllivier Robert 		}
743c0b746e5SOllivier Robert 		else
744c0b746e5SOllivier Robert 		{
745c0b746e5SOllivier Robert 			kernels[0] = "/Placeholder";
746c0b746e5SOllivier Robert 		}
747c0b746e5SOllivier Robert 	}
748c0b746e5SOllivier Robert #endif /* HAVE_GETBOOTFILE */
749c0b746e5SOllivier Robert 	for (kname = kernels; *kname != NULL; kname++)
750c0b746e5SOllivier Robert 	{
751c0b746e5SOllivier Robert 		struct stat stbuf;
752c0b746e5SOllivier Robert 
753c0b746e5SOllivier Robert 		if (stat(*kname, &stbuf) == -1)
754c0b746e5SOllivier Robert 		{
755c0b746e5SOllivier Robert 			continue;
756c0b746e5SOllivier Robert 		}
757c0b746e5SOllivier Robert 		if (nlist(*kname, nl) >= 0)
758c0b746e5SOllivier Robert 		{
759c0b746e5SOllivier Robert 			break;
760c0b746e5SOllivier Robert 		}
761c0b746e5SOllivier Robert 		else
762c0b746e5SOllivier Robert 		{
763c0b746e5SOllivier Robert 			(void) fprintf(stderr,
7649c2daa00SOllivier Robert 				       "%s: nlist didn't find needed symbols from <%s>: %s\n",
7659c2daa00SOllivier Robert 				       progname, *kname, strerror(errno));
766c0b746e5SOllivier Robert 		}
767c0b746e5SOllivier Robert 	}
768c0b746e5SOllivier Robert 	if (*kname == NULL)
769c0b746e5SOllivier Robert 	{
770c0b746e5SOllivier Robert 		(void) fprintf(stderr,
771c0b746e5SOllivier Robert 			       "%s: Couldn't find the kernel\n",
772c0b746e5SOllivier Robert 			       progname);
773c0b746e5SOllivier Robert 		exit(1);
774c0b746e5SOllivier Robert 	}
775c0b746e5SOllivier Robert #endif /* HAVE_KVM_OPEN */
776c0b746e5SOllivier Robert 
777c0b746e5SOllivier Robert 	if (dokmem)
778c0b746e5SOllivier Robert 	{
779c0b746e5SOllivier Robert 		file = kmem;
780c0b746e5SOllivier Robert 
781c0b746e5SOllivier Robert 		fd = openfile(file, O_RDONLY);
782c0b746e5SOllivier Robert #ifdef NLIST_EXTRA_INDIRECTION
783c0b746e5SOllivier Robert 		/*
784c0b746e5SOllivier Robert 		 * Go one more round of indirection.
785c0b746e5SOllivier Robert 		 */
786c0b746e5SOllivier Robert 		for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++)
787c0b746e5SOllivier Robert 		{
788c0b746e5SOllivier Robert 			if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b))
789c0b746e5SOllivier Robert 			{
790c0b746e5SOllivier Robert 				readvar(fd, nl[i].n_value, &nl[i].n_value);
791c0b746e5SOllivier Robert 			}
792c0b746e5SOllivier Robert 		}
793c0b746e5SOllivier Robert #endif /* NLIST_EXTRA_INDIRECTION */
794c0b746e5SOllivier Robert 	}
795c0b746e5SOllivier Robert #endif /* not NOKMEM */
796c0b746e5SOllivier Robert 
797c0b746e5SOllivier Robert 	*tickadj_off  = 0;
798c0b746e5SOllivier Robert 	*tick_off     = 0;
799c0b746e5SOllivier Robert 	*dosync_off   = 0;
800c0b746e5SOllivier Robert 	*noprintf_off = 0;
801c0b746e5SOllivier Robert 
802c0b746e5SOllivier Robert #if defined(N_TICKADJ)
803c0b746e5SOllivier Robert 	*tickadj_off = nl[N_TICKADJ].n_value;
804c0b746e5SOllivier Robert #endif
805c0b746e5SOllivier Robert 
806c0b746e5SOllivier Robert #if defined(N_TICK)
807c0b746e5SOllivier Robert 	*tick_off = nl[N_TICK].n_value;
808c0b746e5SOllivier Robert #endif
809c0b746e5SOllivier Robert 
810c0b746e5SOllivier Robert #if defined(N_DOSYNC)
811c0b746e5SOllivier Robert 	*dosync_off = nl[N_DOSYNC].n_value;
812c0b746e5SOllivier Robert #endif
813c0b746e5SOllivier Robert 
814c0b746e5SOllivier Robert #if defined(N_NOPRINTF)
815c0b746e5SOllivier Robert 	*noprintf_off = nl[N_NOPRINTF].n_value;
816c0b746e5SOllivier Robert #endif
817c0b746e5SOllivier Robert 	return;
818c0b746e5SOllivier Robert }
819c0b746e5SOllivier Robert 
820c0b746e5SOllivier Robert #undef N_TICKADJ
821c0b746e5SOllivier Robert #undef N_TICK
822c0b746e5SOllivier Robert #undef N_DOSYNC
823c0b746e5SOllivier Robert #undef N_NOPRINTF
824c0b746e5SOllivier Robert 
825c0b746e5SOllivier Robert 
826c0b746e5SOllivier Robert /*
827c0b746e5SOllivier Robert  * openfile - open the file, check for errors
828c0b746e5SOllivier Robert  */
829c0b746e5SOllivier Robert static int
openfile(const char * name,int mode)830c0b746e5SOllivier Robert openfile(
831c0b746e5SOllivier Robert 	const char *name,
832c0b746e5SOllivier Robert 	int mode
833c0b746e5SOllivier Robert 	)
834c0b746e5SOllivier Robert {
835c0b746e5SOllivier Robert 	int ifd;
836c0b746e5SOllivier Robert 
837c0b746e5SOllivier Robert 	ifd = open(name, mode);
838c0b746e5SOllivier Robert 	if (ifd < 0)
839c0b746e5SOllivier Robert 	{
840c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: open %s: ", progname, name);
841c0b746e5SOllivier Robert 		perror("");
842c0b746e5SOllivier Robert 		exit(1);
843c0b746e5SOllivier Robert 	}
844c0b746e5SOllivier Robert 	return ifd;
845c0b746e5SOllivier Robert }
846c0b746e5SOllivier Robert 
847c0b746e5SOllivier Robert 
848c0b746e5SOllivier Robert /*
849c0b746e5SOllivier Robert  * writevar - write a variable into the file
850c0b746e5SOllivier Robert  */
851c0b746e5SOllivier Robert static void
writevar(int ofd,off_t off,int var)852c0b746e5SOllivier Robert writevar(
853c0b746e5SOllivier Robert 	int ofd,
854c0b746e5SOllivier Robert 	off_t off,
855c0b746e5SOllivier Robert 	int var
856c0b746e5SOllivier Robert 	)
857c0b746e5SOllivier Robert {
858c0b746e5SOllivier Robert 
859c0b746e5SOllivier Robert 	if (lseek(ofd, off, L_SET) == -1)
860c0b746e5SOllivier Robert 	{
861c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: lseek fails: ", progname);
862c0b746e5SOllivier Robert 		perror("");
863c0b746e5SOllivier Robert 		exit(1);
864c0b746e5SOllivier Robert 	}
865c0b746e5SOllivier Robert 	if (write(ofd, (char *)&var, sizeof(int)) != sizeof(int))
866c0b746e5SOllivier Robert 	{
867c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: write fails: ", progname);
868c0b746e5SOllivier Robert 		perror("");
869c0b746e5SOllivier Robert 		exit(1);
870c0b746e5SOllivier Robert 	}
871c0b746e5SOllivier Robert 	return;
872c0b746e5SOllivier Robert }
873c0b746e5SOllivier Robert 
874c0b746e5SOllivier Robert 
875c0b746e5SOllivier Robert /*
876c0b746e5SOllivier Robert  * readvar - read a variable from the file
877c0b746e5SOllivier Robert  */
878c0b746e5SOllivier Robert static void
readvar(int ifd,off_t off,int * var)879c0b746e5SOllivier Robert readvar(
880c0b746e5SOllivier Robert 	int ifd,
881c0b746e5SOllivier Robert 	off_t off,
882c0b746e5SOllivier Robert 	int *var
883c0b746e5SOllivier Robert 	)
884c0b746e5SOllivier Robert {
885c0b746e5SOllivier Robert 	int i;
886c0b746e5SOllivier Robert 
887c0b746e5SOllivier Robert 	if (lseek(ifd, off, L_SET) == -1)
888c0b746e5SOllivier Robert 	{
889c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: lseek fails: ", progname);
890c0b746e5SOllivier Robert 		perror("");
891c0b746e5SOllivier Robert 		exit(1);
892c0b746e5SOllivier Robert 	}
893c0b746e5SOllivier Robert 	i = read(ifd, (char *)var, sizeof(int));
894c0b746e5SOllivier Robert 	if (i < 0)
895c0b746e5SOllivier Robert 	{
896c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: read fails: ", progname);
897c0b746e5SOllivier Robert 		perror("");
898c0b746e5SOllivier Robert 		exit(1);
899c0b746e5SOllivier Robert 	}
900c0b746e5SOllivier Robert 	if (i != sizeof(int))
901c0b746e5SOllivier Robert 	{
902c0b746e5SOllivier Robert 		(void) fprintf(stderr, "%s: read expected %d, got %d\n",
903c0b746e5SOllivier Robert 			       progname, (int)sizeof(int), i);
904c0b746e5SOllivier Robert 		exit(1);
905c0b746e5SOllivier Robert 	}
906c0b746e5SOllivier Robert 	return;
907c0b746e5SOllivier Robert }
908c0b746e5SOllivier Robert #endif /* not Linux */
909