xref: /netbsd-src/external/bsd/ntp/dist/libntp/machines.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: machines.c,v 1.7 2024/08/18 20:47:13 christos Exp $	*/
2abb0f93cSkardel 
3abb0f93cSkardel /* machines.c - provide special support for peculiar architectures
4abb0f93cSkardel  *
5abb0f93cSkardel  * Real bummers unite !
6abb0f93cSkardel  *
7abb0f93cSkardel  */
8abb0f93cSkardel 
9abb0f93cSkardel #ifdef HAVE_CONFIG_H
10abb0f93cSkardel #include "config.h"
11abb0f93cSkardel #endif
12abb0f93cSkardel 
13f003fb54Skardel #include "ntp.h"
14abb0f93cSkardel #include "ntp_machine.h"
15abb0f93cSkardel #include "ntp_syslog.h"
16abb0f93cSkardel #include "ntp_stdlib.h"
17abb0f93cSkardel #include "ntp_unixtime.h"
188585484eSchristos #include "ntp_debug.h"
19*eabc0478Schristos #include "ntp_tty.h"
20abb0f93cSkardel 
21abb0f93cSkardel #ifdef HAVE_UNISTD_H
22abb0f93cSkardel #include <unistd.h>
23abb0f93cSkardel #endif
24abb0f93cSkardel 
25abb0f93cSkardel #ifdef SYS_WINNT
26*eabc0478Schristos #include <conio.h>
27abb0f93cSkardel #else
28abb0f93cSkardel #ifdef SYS_VXWORKS
29abb0f93cSkardel #include "taskLib.h"
30abb0f93cSkardel #include "sysLib.h"
31abb0f93cSkardel #include "time.h"
32abb0f93cSkardel #include "ntp_syslog.h"
33abb0f93cSkardel 
34abb0f93cSkardel /*	some translations to the world of vxWorkings -casey */
35abb0f93cSkardel /* first some netdb type things */
36abb0f93cSkardel #include "ioLib.h"
37abb0f93cSkardel #include <socket.h>
38abb0f93cSkardel int h_errno;
39abb0f93cSkardel 
40abb0f93cSkardel struct hostent *gethostbyname(char *name)
41abb0f93cSkardel 	{
42abb0f93cSkardel 	struct hostent *host1;
43abb0f93cSkardel 	h_errno = 0;					/* we are always successful!!! */
44af12ab5eSchristos 	host1 = (struct hostent *) emalloc (sizeof(struct hostent));
45abb0f93cSkardel 	host1->h_name = name;
46abb0f93cSkardel 	host1->h_addrtype = AF_INET;
47abb0f93cSkardel 	host1->h_aliases = name;
48abb0f93cSkardel 	host1->h_length = 4;
49abb0f93cSkardel 	host1->h_addr_list[0] = (char *)hostGetByName (name);
50abb0f93cSkardel 	host1->h_addr_list[1] = NULL;
51abb0f93cSkardel 	return host1;
52abb0f93cSkardel 	}
53abb0f93cSkardel 
54abb0f93cSkardel struct hostent *gethostbyaddr(char *name, int size, int addr_type)
55abb0f93cSkardel 	{
56abb0f93cSkardel 	struct hostent *host1;
57abb0f93cSkardel 	h_errno = 0;  /* we are always successful!!! */
58af12ab5eSchristos 	host1 = (struct hostent *) emalloc (sizeof(struct hostent));
59abb0f93cSkardel 	host1->h_name = name;
60abb0f93cSkardel 	host1->h_addrtype = AF_INET;
61abb0f93cSkardel 	host1->h_aliases = name;
62abb0f93cSkardel 	host1->h_length = 4;
63abb0f93cSkardel 	host1->h_addr_list = NULL;
64abb0f93cSkardel 	return host1;
65abb0f93cSkardel 	}
66abb0f93cSkardel 
67abb0f93cSkardel struct servent *getservbyname (char *name, char *type)
68abb0f93cSkardel 	{
69abb0f93cSkardel 	struct servent *serv1;
70af12ab5eSchristos 	serv1 = (struct servent *) emalloc (sizeof(struct servent));
71abb0f93cSkardel 	serv1->s_name = "ntp";      /* official service name */
72abb0f93cSkardel 	serv1->s_aliases = NULL;	/* alias list */
73abb0f93cSkardel 	serv1->s_port = 123;		/* port # */
74abb0f93cSkardel 	serv1->s_proto = "udp";     /* protocol to use */
75abb0f93cSkardel 	return serv1;
76abb0f93cSkardel 	}
77abb0f93cSkardel 
78abb0f93cSkardel /* second
79abb0f93cSkardel  * vxworks thinks it has insomnia
80abb0f93cSkardel  * we have to sleep for number of seconds
81abb0f93cSkardel  */
82abb0f93cSkardel 
83abb0f93cSkardel #define CLKRATE 	sysClkRateGet()
84abb0f93cSkardel 
85abb0f93cSkardel /* I am not sure how valid the granularity is - it is from G. Eger's port */
86abb0f93cSkardel #define CLK_GRANULARITY  1		/* Granularity of system clock in usec	*/
87abb0f93cSkardel 								/* Used to round down # usecs/tick		*/
88abb0f93cSkardel 								/* On a VCOM-100, PIT gets 8 MHz clk,	*/
89abb0f93cSkardel 								/*	& it prescales by 32, thus 4 usec	*/
90abb0f93cSkardel 								/* on mv167, granularity is 1usec anyway*/
91abb0f93cSkardel 								/* To defeat rounding, set to 1 		*/
92abb0f93cSkardel #define USECS_PER_SEC		MILLION		/* Microseconds per second	*/
93abb0f93cSkardel #define TICK (((USECS_PER_SEC / CLKRATE) / CLK_GRANULARITY) * CLK_GRANULARITY)
94abb0f93cSkardel 
95abb0f93cSkardel /* emulate unix sleep
96abb0f93cSkardel  * casey
97abb0f93cSkardel  */
98abb0f93cSkardel void sleep(int seconds)
99abb0f93cSkardel 	{
100abb0f93cSkardel 	taskDelay(seconds*TICK);
101abb0f93cSkardel 	}
102abb0f93cSkardel /* emulate unix alarm
103abb0f93cSkardel  * that pauses and calls SIGALRM after the seconds are up...
104abb0f93cSkardel  * so ... taskDelay() fudged for seconds should amount to the same thing.
105abb0f93cSkardel  * casey
106abb0f93cSkardel  */
107abb0f93cSkardel void alarm (int seconds)
108abb0f93cSkardel 	{
109abb0f93cSkardel 	sleep(seconds);
110abb0f93cSkardel 	}
111abb0f93cSkardel 
112abb0f93cSkardel #endif /* SYS_VXWORKS */
113abb0f93cSkardel 
114abb0f93cSkardel #ifdef SYS_PTX			/* Does PTX still need this? */
115abb0f93cSkardel /*#include <sys/types.h>	*/
116abb0f93cSkardel #include <sys/procstats.h>
117abb0f93cSkardel 
118abb0f93cSkardel int
119abb0f93cSkardel gettimeofday(
120abb0f93cSkardel 	struct timeval *tvp
121abb0f93cSkardel 	)
122abb0f93cSkardel {
123abb0f93cSkardel 	/*
124abb0f93cSkardel 	 * hi, this is Sequents sneak path to get to a clock
125abb0f93cSkardel 	 * this is also the most logical syscall for such a function
126abb0f93cSkardel 	 */
127abb0f93cSkardel 	return (get_process_stats(tvp, PS_SELF, (struct procstats *) 0,
128abb0f93cSkardel 				  (struct procstats *) 0));
129abb0f93cSkardel }
130abb0f93cSkardel #endif /* SYS_PTX */
131abb0f93cSkardel 
132abb0f93cSkardel #ifdef MPE
133abb0f93cSkardel /* This is a substitute for bind() that if called for an AF_INET socket
134abb0f93cSkardel port less than 1024, GETPRIVMODE() and GETUSERMODE() calls will be done. */
135abb0f93cSkardel 
136abb0f93cSkardel #undef bind
137abb0f93cSkardel #include <sys/types.h>
138abb0f93cSkardel #include <sys/socket.h>
139abb0f93cSkardel #include <netinet/in.h>
140abb0f93cSkardel #include <sys/un.h>
141abb0f93cSkardel 
142abb0f93cSkardel extern void GETPRIVMODE(void);
143abb0f93cSkardel extern void GETUSERMODE(void);
144abb0f93cSkardel 
145abb0f93cSkardel int __ntp_mpe_bind(int s, void *addr, int addrlen);
146abb0f93cSkardel 
147abb0f93cSkardel int __ntp_mpe_bind(int s, void *addr, int addrlen) {
148abb0f93cSkardel 	int priv = 0;
149abb0f93cSkardel 	int result;
150abb0f93cSkardel 
151abb0f93cSkardel if (addrlen == sizeof(struct sockaddr_in)) { /* AF_INET */
152abb0f93cSkardel 	if (((struct sockaddr_in *)addr)->sin_port > 0 &&
153abb0f93cSkardel 	    ((struct sockaddr_in *)addr)->sin_port < 1024) {
154abb0f93cSkardel 		priv = 1;
155abb0f93cSkardel 		GETPRIVMODE();
156abb0f93cSkardel 	}
157abb0f93cSkardel /*	((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; */
158abb0f93cSkardel 	result = bind(s,addr,addrlen);
159abb0f93cSkardel 	if (priv == 1) GETUSERMODE();
160abb0f93cSkardel } else /* AF_UNIX */
161abb0f93cSkardel 	result = bind(s,addr,addrlen);
162abb0f93cSkardel 
163abb0f93cSkardel return result;
164abb0f93cSkardel }
165abb0f93cSkardel 
166abb0f93cSkardel /*
167abb0f93cSkardel  * MPE stupidly requires sfcntl() to be used on sockets instead of fcntl(),
168abb0f93cSkardel  * so we define a wrapper to analyze the file descriptor and call the correct
169abb0f93cSkardel  * function.
170abb0f93cSkardel  */
171abb0f93cSkardel 
172abb0f93cSkardel #undef fcntl
173abb0f93cSkardel #include <errno.h>
174abb0f93cSkardel #include <fcntl.h>
175abb0f93cSkardel 
176abb0f93cSkardel int __ntp_mpe_fcntl(int fd, int cmd, int arg);
177abb0f93cSkardel 
178abb0f93cSkardel int __ntp_mpe_fcntl(int fd, int cmd, int arg) {
179abb0f93cSkardel 	int len;
180abb0f93cSkardel 	struct sockaddr sa;
181abb0f93cSkardel 
182abb0f93cSkardel 	extern int sfcntl(int, int, int);
183abb0f93cSkardel 
184abb0f93cSkardel 	len = sizeof sa;
185abb0f93cSkardel 	if (getsockname(fd, &sa, &len) == -1) {
186abb0f93cSkardel 		if (errno == EAFNOSUPPORT) /* AF_UNIX socket */
187abb0f93cSkardel 			return sfcntl(fd, cmd, arg);
188abb0f93cSkardel 		if (errno == ENOTSOCK) /* file or pipe */
189abb0f93cSkardel 			return fcntl(fd, cmd, arg);
190abb0f93cSkardel 		return (-1); /* unknown getsockname() failure */
191abb0f93cSkardel 	} else /* AF_INET socket */
192abb0f93cSkardel 		return sfcntl(fd, cmd, arg);
193abb0f93cSkardel }
194abb0f93cSkardel 
195abb0f93cSkardel /*
196abb0f93cSkardel  * Setitimer emulation support.  Note that we implement this using alarm(),
197abb0f93cSkardel  * and since alarm() only delivers one signal, we must re-enable the alarm
198abb0f93cSkardel  * by enabling our own SIGALRM setitimer_mpe_handler routine to be called
199abb0f93cSkardel  * before the real handler routine and re-enable the alarm at that time.
200abb0f93cSkardel  *
201abb0f93cSkardel  * Note that this solution assumes that sigaction(SIGALRM) is called before
202abb0f93cSkardel  * calling setitimer().  If it should ever to become necessary to support
203abb0f93cSkardel  * sigaction(SIGALRM) after calling setitimer(), it will be necessary to trap
204abb0f93cSkardel  * those sigaction() calls.
205abb0f93cSkardel  */
206abb0f93cSkardel 
207abb0f93cSkardel #include <limits.h>
208abb0f93cSkardel #include <signal.h>
209abb0f93cSkardel 
210abb0f93cSkardel /*
211abb0f93cSkardel  * Some global data that needs to be shared between setitimer() and
212abb0f93cSkardel  * setitimer_mpe_handler().
213abb0f93cSkardel  */
214abb0f93cSkardel 
215abb0f93cSkardel struct {
216abb0f93cSkardel 	unsigned long current_msec;	/* current alarm() value in effect */
217abb0f93cSkardel 	unsigned long interval_msec;	/* next alarm() value from setitimer */
218abb0f93cSkardel 	unsigned long value_msec;	/* first alarm() value from setitimer */
219abb0f93cSkardel 	struct itimerval current_itimerval; /* current itimerval in effect */
220abb0f93cSkardel 	struct sigaction oldact;	/* SIGALRM state saved by setitimer */
221abb0f93cSkardel } setitimer_mpe_ctx = { 0, 0, 0 };
222abb0f93cSkardel 
223abb0f93cSkardel /*
224abb0f93cSkardel  * Undocumented, unsupported function to do alarm() in milliseconds.
225abb0f93cSkardel  */
226abb0f93cSkardel 
227abb0f93cSkardel extern unsigned int px_alarm(unsigned long, int *);
228abb0f93cSkardel 
229abb0f93cSkardel /*
230abb0f93cSkardel  * The SIGALRM handler routine enabled by setitimer().  Re-enable the alarm or
231abb0f93cSkardel  * restore the original SIGALRM setting if no more alarms are needed.  Then
232abb0f93cSkardel  * call the original SIGALRM handler (if any).
233abb0f93cSkardel  */
234abb0f93cSkardel 
235abb0f93cSkardel static RETSIGTYPE setitimer_mpe_handler(int sig)
236abb0f93cSkardel {
237abb0f93cSkardel int alarm_hpe_status;
238abb0f93cSkardel 
239abb0f93cSkardel /* Update the new current alarm value */
240abb0f93cSkardel 
241abb0f93cSkardel setitimer_mpe_ctx.current_msec = setitimer_mpe_ctx.interval_msec;
242abb0f93cSkardel 
243abb0f93cSkardel if (setitimer_mpe_ctx.interval_msec > 0) {
244abb0f93cSkardel   /* Additional intervals needed; re-arm the alarm timer */
245abb0f93cSkardel   px_alarm(setitimer_mpe_ctx.interval_msec,&alarm_hpe_status);
246abb0f93cSkardel } else {
247abb0f93cSkardel   /* No more intervals, so restore previous original SIGALRM handler */
248abb0f93cSkardel   sigaction(SIGALRM, &setitimer_mpe_ctx.oldact, NULL);
249abb0f93cSkardel }
250abb0f93cSkardel 
251abb0f93cSkardel /* Call the original SIGALRM handler if it is a function and not just a flag */
252abb0f93cSkardel 
253abb0f93cSkardel if (setitimer_mpe_ctx.oldact.sa_handler != SIG_DFL &&
254abb0f93cSkardel     setitimer_mpe_ctx.oldact.sa_handler != SIG_ERR &&
255abb0f93cSkardel     setitimer_mpe_ctx.oldact.sa_handler != SIG_IGN)
256abb0f93cSkardel   (*setitimer_mpe_ctx.oldact.sa_handler)(SIGALRM);
257abb0f93cSkardel 
258abb0f93cSkardel }
259abb0f93cSkardel 
260abb0f93cSkardel /*
261abb0f93cSkardel  * Our implementation of setitimer().
262abb0f93cSkardel  */
263abb0f93cSkardel 
264abb0f93cSkardel int
265abb0f93cSkardel setitimer(int which, struct itimerval *value,
266abb0f93cSkardel 	    struct itimerval *ovalue)
267abb0f93cSkardel {
268abb0f93cSkardel 
269abb0f93cSkardel int alarm_hpe_status;
270abb0f93cSkardel unsigned long remaining_msec, value_msec, interval_msec;
271abb0f93cSkardel struct sigaction newact;
272abb0f93cSkardel 
273abb0f93cSkardel /*
274abb0f93cSkardel  * Convert the initial interval to milliseconds
275abb0f93cSkardel  */
276abb0f93cSkardel 
277abb0f93cSkardel if (value->it_value.tv_sec > (UINT_MAX / 1000))
278abb0f93cSkardel   value_msec = UINT_MAX;
279abb0f93cSkardel else
280abb0f93cSkardel   value_msec = value->it_value.tv_sec * 1000;
281abb0f93cSkardel 
282abb0f93cSkardel value_msec += value->it_value.tv_usec / 1000;
283abb0f93cSkardel 
284abb0f93cSkardel /*
285abb0f93cSkardel  * Convert the reset interval to milliseconds
286abb0f93cSkardel  */
287abb0f93cSkardel 
288abb0f93cSkardel if (value->it_interval.tv_sec > (UINT_MAX / 1000))
289abb0f93cSkardel   interval_msec = UINT_MAX;
290abb0f93cSkardel else
291abb0f93cSkardel   interval_msec = value->it_interval.tv_sec * 1000;
292abb0f93cSkardel 
293abb0f93cSkardel interval_msec += value->it_interval.tv_usec / 1000;
294abb0f93cSkardel 
295abb0f93cSkardel if (value_msec > 0 && interval_msec > 0) {
296abb0f93cSkardel   /*
297abb0f93cSkardel    * We'll be starting an interval timer that will be repeating, so we need to
298abb0f93cSkardel    * insert our own SIGALRM signal handler to schedule the repeats.
299abb0f93cSkardel    */
300abb0f93cSkardel 
301abb0f93cSkardel   /* Read the current SIGALRM action */
302abb0f93cSkardel 
303abb0f93cSkardel   if (sigaction(SIGALRM, NULL, &setitimer_mpe_ctx.oldact) < 0) {
304abb0f93cSkardel     fprintf(stderr,"MPE setitimer old handler failed, errno=%d\n",errno);
305abb0f93cSkardel     return -1;
306abb0f93cSkardel   }
307abb0f93cSkardel 
308abb0f93cSkardel   /* Initialize the new action to call our SIGALRM handler instead */
309abb0f93cSkardel 
310abb0f93cSkardel   newact.sa_handler = &setitimer_mpe_handler;
311abb0f93cSkardel   newact.sa_mask = setitimer_mpe_ctx.oldact.sa_mask;
312abb0f93cSkardel   newact.sa_flags = setitimer_mpe_ctx.oldact.sa_flags;
313abb0f93cSkardel 
314abb0f93cSkardel   if (sigaction(SIGALRM, &newact, NULL) < 0) {
315abb0f93cSkardel     fprintf(stderr,"MPE setitimer new handler failed, errno=%d\n",errno);
316abb0f93cSkardel     return -1;
317abb0f93cSkardel   }
318abb0f93cSkardel }
319abb0f93cSkardel 
320abb0f93cSkardel /*
321abb0f93cSkardel  * Return previous itimerval if desired
322abb0f93cSkardel  */
323abb0f93cSkardel 
324abb0f93cSkardel if (ovalue != NULL) *ovalue = setitimer_mpe_ctx.current_itimerval;
325abb0f93cSkardel 
326abb0f93cSkardel /*
327abb0f93cSkardel  * Save current parameters for later usage
328abb0f93cSkardel  */
329abb0f93cSkardel 
330abb0f93cSkardel setitimer_mpe_ctx.current_itimerval = *value;
331abb0f93cSkardel setitimer_mpe_ctx.current_msec = value_msec;
332abb0f93cSkardel setitimer_mpe_ctx.value_msec = value_msec;
333abb0f93cSkardel setitimer_mpe_ctx.interval_msec = interval_msec;
334abb0f93cSkardel 
335abb0f93cSkardel /*
336abb0f93cSkardel  * Schedule the first alarm
337abb0f93cSkardel  */
338abb0f93cSkardel 
339abb0f93cSkardel remaining_msec = px_alarm(value_msec, &alarm_hpe_status);
340abb0f93cSkardel if (alarm_hpe_status == 0)
341abb0f93cSkardel   return (0);
342abb0f93cSkardel else
343abb0f93cSkardel   return (-1);
344abb0f93cSkardel }
345abb0f93cSkardel 
346abb0f93cSkardel /*
347abb0f93cSkardel  * MPE lacks gettimeofday(), so we define our own.
348abb0f93cSkardel  */
349abb0f93cSkardel 
350abb0f93cSkardel int gettimeofday(struct timeval *tvp)
351abb0f93cSkardel 
352abb0f93cSkardel {
353abb0f93cSkardel /* Documented, supported MPE functions. */
354abb0f93cSkardel extern void GETPRIVMODE(void);
355abb0f93cSkardel extern void GETUSERMODE(void);
356abb0f93cSkardel 
357abb0f93cSkardel /* Undocumented, unsupported MPE functions. */
358abb0f93cSkardel extern long long get_time(void);
359abb0f93cSkardel extern void get_time_change_info(long long *, char *, char *);
360abb0f93cSkardel extern long long ticks_to_micro(long long);
361abb0f93cSkardel 
362abb0f93cSkardel char pwf_since_boot, recover_pwf_time;
363abb0f93cSkardel long long mpetime, offset_ticks, offset_usec;
364abb0f93cSkardel 
365abb0f93cSkardel GETPRIVMODE();
366abb0f93cSkardel mpetime = get_time(); /* MPE local time usecs since Jan 1 1970 */
367abb0f93cSkardel get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
368abb0f93cSkardel offset_usec = ticks_to_micro(offset_ticks);  /* UTC offset usecs */
369abb0f93cSkardel GETUSERMODE();
370abb0f93cSkardel 
371abb0f93cSkardel mpetime = mpetime - offset_usec;  /* Convert from local time to UTC */
372abb0f93cSkardel tvp->tv_sec = mpetime / 1000000LL;
373abb0f93cSkardel tvp->tv_usec = mpetime % 1000000LL;
374abb0f93cSkardel 
375abb0f93cSkardel return 0;
376abb0f93cSkardel }
377abb0f93cSkardel 
378abb0f93cSkardel /*
379abb0f93cSkardel  * MPE lacks settimeofday(), so we define our own.
380abb0f93cSkardel  */
381abb0f93cSkardel 
382abb0f93cSkardel #define HAVE_SETTIMEOFDAY
383abb0f93cSkardel 
384abb0f93cSkardel int settimeofday(struct timeval *tvp)
385abb0f93cSkardel 
386abb0f93cSkardel {
387abb0f93cSkardel /* Documented, supported MPE functions. */
388abb0f93cSkardel extern void GETPRIVMODE(void);
389abb0f93cSkardel extern void GETUSERMODE(void);
390abb0f93cSkardel 
391abb0f93cSkardel /* Undocumented, unsupported MPE functions. */
392abb0f93cSkardel extern void get_time_change_info(long long *, char *, char *);
393abb0f93cSkardel extern void initialize_system_time(long long, int);
394abb0f93cSkardel extern void set_time_correction(long long, int, int);
395abb0f93cSkardel extern long long ticks_to_micro(long long);
396abb0f93cSkardel 
397abb0f93cSkardel char pwf_since_boot, recover_pwf_time;
398abb0f93cSkardel long long big_sec, big_usec, mpetime, offset_ticks, offset_usec;
399abb0f93cSkardel 
400abb0f93cSkardel big_sec = tvp->tv_sec;
401abb0f93cSkardel big_usec = tvp->tv_usec;
402abb0f93cSkardel mpetime = (big_sec * 1000000LL) + big_usec;  /* Desired UTC microseconds */
403abb0f93cSkardel 
404abb0f93cSkardel GETPRIVMODE();
405abb0f93cSkardel set_time_correction(0LL,0,0); /* Cancel previous time correction, if any */
406abb0f93cSkardel get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
407abb0f93cSkardel offset_usec = ticks_to_micro(offset_ticks); /* UTC offset microseconds */
408abb0f93cSkardel mpetime = mpetime + offset_usec; /* Convert from UTC to local time */
409abb0f93cSkardel initialize_system_time(mpetime,1);
410abb0f93cSkardel GETUSERMODE();
411abb0f93cSkardel 
412abb0f93cSkardel return 0;
413abb0f93cSkardel }
414abb0f93cSkardel #endif /* MPE */
415abb0f93cSkardel 
416abb0f93cSkardel #define SET_TOD_UNDETERMINED	0
417abb0f93cSkardel #define SET_TOD_CLOCK_SETTIME	1
418abb0f93cSkardel #define SET_TOD_SETTIMEOFDAY	2
419abb0f93cSkardel #define SET_TOD_STIME		3
420abb0f93cSkardel 
421abb0f93cSkardel const char * const set_tod_used[] = {
422abb0f93cSkardel 	"undetermined",
423abb0f93cSkardel 	"clock_settime",
424abb0f93cSkardel 	"settimeofday",
425abb0f93cSkardel 	"stime"
426abb0f93cSkardel };
427abb0f93cSkardel 
428abb0f93cSkardel pset_tod_using	set_tod_using = NULL;
429abb0f93cSkardel 
430abb0f93cSkardel 
431abb0f93cSkardel int
432abb0f93cSkardel ntp_set_tod(
433abb0f93cSkardel 	struct timeval *tvp,
434abb0f93cSkardel 	void *tzp
435abb0f93cSkardel 	)
436abb0f93cSkardel {
437abb0f93cSkardel 	static int	tod;
4388585484eSchristos 	int		rc;
4398585484eSchristos 	int		saved_errno;
440abb0f93cSkardel 
4418585484eSchristos 	TRACE(1, ("In ntp_set_tod\n"));
4428585484eSchristos 	rc = -1;
4438585484eSchristos 	saved_errno = 0;
444abb0f93cSkardel 
445abb0f93cSkardel #ifdef HAVE_CLOCK_SETTIME
446abb0f93cSkardel 	if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) {
447abb0f93cSkardel 		struct timespec ts;
448abb0f93cSkardel 
449abb0f93cSkardel 		/* Convert timeval to timespec */
450abb0f93cSkardel 		ts.tv_sec = tvp->tv_sec;
451abb0f93cSkardel 		ts.tv_nsec = 1000 *  tvp->tv_usec;
452abb0f93cSkardel 
453abb0f93cSkardel 		errno = 0;
454abb0f93cSkardel 		rc = clock_settime(CLOCK_REALTIME, &ts);
455abb0f93cSkardel 		saved_errno = errno;
4568585484eSchristos 		TRACE(1, ("ntp_set_tod: clock_settime: %d %m\n", rc));
457abb0f93cSkardel 		if (!tod && !rc)
458abb0f93cSkardel 			tod = SET_TOD_CLOCK_SETTIME;
459abb0f93cSkardel 
460abb0f93cSkardel 	}
461abb0f93cSkardel #endif /* HAVE_CLOCK_SETTIME */
462abb0f93cSkardel #ifdef HAVE_SETTIMEOFDAY
463abb0f93cSkardel 	if (rc && (SET_TOD_SETTIMEOFDAY == tod || !tod)) {
464abb0f93cSkardel 		struct timeval adjtv;
465abb0f93cSkardel 
466abb0f93cSkardel 		/*
467abb0f93cSkardel 		 * Some broken systems don't reset adjtime() when the
468abb0f93cSkardel 		 * clock is stepped.
469abb0f93cSkardel 		 */
470abb0f93cSkardel 		adjtv.tv_sec = adjtv.tv_usec = 0;
471abb0f93cSkardel 		adjtime(&adjtv, NULL);
472abb0f93cSkardel 		errno = 0;
473abb0f93cSkardel 		rc = SETTIMEOFDAY(tvp, tzp);
474abb0f93cSkardel 		saved_errno = errno;
4758585484eSchristos 		TRACE(1, ("ntp_set_tod: settimeofday: %d %m\n", rc));
476abb0f93cSkardel 		if (!tod && !rc)
477abb0f93cSkardel 			tod = SET_TOD_SETTIMEOFDAY;
478abb0f93cSkardel 	}
479abb0f93cSkardel #endif /* HAVE_SETTIMEOFDAY */
480abb0f93cSkardel #ifdef HAVE_STIME
481abb0f93cSkardel 	if (rc && (SET_TOD_STIME == tod || !tod)) {
482abb0f93cSkardel 		long tp = tvp->tv_sec;
483abb0f93cSkardel 
484abb0f93cSkardel 		errno = 0;
485abb0f93cSkardel 		rc = stime(&tp); /* lie as bad as SysVR4 */
486abb0f93cSkardel 		saved_errno = errno;
4878585484eSchristos 		TRACE(1, ("ntp_set_tod: stime: %d %m\n", rc));
488abb0f93cSkardel 		if (!tod && !rc)
489abb0f93cSkardel 			tod = SET_TOD_STIME;
490abb0f93cSkardel 	}
491abb0f93cSkardel #endif /* HAVE_STIME */
492abb0f93cSkardel 
4938585484eSchristos 	errno = saved_errno;	/* for %m below */
4948585484eSchristos 	TRACE(1, ("ntp_set_tod: Final result: %s: %d %m\n",
4958585484eSchristos 		  set_tod_used[tod], rc));
496abb0f93cSkardel 	/*
497abb0f93cSkardel 	 * Say how we're setting the time of day
498abb0f93cSkardel 	 */
499abb0f93cSkardel 	if (!rc && NULL != set_tod_using) {
500abb0f93cSkardel 		(*set_tod_using)(set_tod_used[tod]);
501abb0f93cSkardel 		set_tod_using = NULL;
502abb0f93cSkardel 	}
503abb0f93cSkardel 
504abb0f93cSkardel 	if (rc)
505abb0f93cSkardel 		errno = saved_errno;
506abb0f93cSkardel 
507abb0f93cSkardel 	return rc;
508abb0f93cSkardel }
509abb0f93cSkardel 
510abb0f93cSkardel #endif /* not SYS_WINNT */
511abb0f93cSkardel 
512abb0f93cSkardel #if defined (SYS_WINNT) || defined (SYS_VXWORKS) || defined(MPE)
513abb0f93cSkardel /* getpass is used in ntpq.c and ntpdc.c */
514abb0f93cSkardel 
515abb0f93cSkardel char *
516abb0f93cSkardel getpass(const char * prompt)
517abb0f93cSkardel {
518abb0f93cSkardel 	int c, i;
519abb0f93cSkardel 	static char password[32];
520abb0f93cSkardel 
521abb0f93cSkardel 	fprintf(stderr, "%s", prompt);
522abb0f93cSkardel 	fflush(stderr);
523abb0f93cSkardel 
524abb0f93cSkardel 	for (i=0; i<sizeof(password)-1 && ((c=_getch())!='\n' && c!='\r'); i++) {
525abb0f93cSkardel 		password[i] = (char) c;
526abb0f93cSkardel 	}
527abb0f93cSkardel 	password[i] = '\0';
528abb0f93cSkardel 
529abb0f93cSkardel 	fputc('\n', stderr);
530abb0f93cSkardel 	fflush(stderr);
531abb0f93cSkardel 
532abb0f93cSkardel 	return password;
533abb0f93cSkardel }
534abb0f93cSkardel #endif /* SYS_WINNT */
535*eabc0478Schristos 
536*eabc0478Schristos 
537*eabc0478Schristos static const int baudTable[][2] = {
538*eabc0478Schristos 	{B0, 0},
539*eabc0478Schristos 	{B50, 50},
540*eabc0478Schristos 	{B75, 75},
541*eabc0478Schristos 	{B110, 110},
542*eabc0478Schristos 	{B134, 134},
543*eabc0478Schristos 	{B150, 150},
544*eabc0478Schristos 	{B200, 200},
545*eabc0478Schristos 	{B300, 300},
546*eabc0478Schristos 	{B600, 600},
547*eabc0478Schristos 	{B1200, 1200},
548*eabc0478Schristos 	{B1800, 1800},
549*eabc0478Schristos 	{B2400, 2400},
550*eabc0478Schristos 	{B4800, 4800},
551*eabc0478Schristos 	{B9600, 9600},
552*eabc0478Schristos 	{B19200, 19200},
553*eabc0478Schristos 	{B38400, 38400},
554*eabc0478Schristos #   ifdef B57600
555*eabc0478Schristos 	{B57600, 57600 },
556*eabc0478Schristos #   endif
557*eabc0478Schristos #   ifdef B115200
558*eabc0478Schristos 	{B115200, 115200},
559*eabc0478Schristos #   endif
560*eabc0478Schristos 	{-1, -1}
561*eabc0478Schristos };
562*eabc0478Schristos 
563*eabc0478Schristos 
564*eabc0478Schristos int  symBaud2numBaud(int symBaud)
565*eabc0478Schristos {
566*eabc0478Schristos 	int i;
567*eabc0478Schristos 
568*eabc0478Schristos 	for (i = 0; baudTable[i][1] >= 0; ++i) {
569*eabc0478Schristos 		if (baudTable[i][0] == symBaud) {
570*eabc0478Schristos 			break;
571*eabc0478Schristos 		}
572*eabc0478Schristos 	}
573*eabc0478Schristos 	return baudTable[i][1];
574*eabc0478Schristos }
575*eabc0478Schristos 
576*eabc0478Schristos 
577*eabc0478Schristos #if 0	/* unused */
578*eabc0478Schristos int  numBaud2symBaud(int numBaud)
579*eabc0478Schristos {
580*eabc0478Schristos 	int i;
581*eabc0478Schristos 
582*eabc0478Schristos 	for (i = 0; baudTable[i][1] >= 0; ++i) {
583*eabc0478Schristos 		if (baudTable[i][1] == numBaud) {
584*eabc0478Schristos 			break;
585*eabc0478Schristos 		}
586*eabc0478Schristos 	}
587*eabc0478Schristos 	return baudTable[i][0];
588*eabc0478Schristos }
589*eabc0478Schristos #endif	/* unused fn */
590