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