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