154359Sroberto/* machines.c - provide special support for peculiar architectures 254359Sroberto * 354359Sroberto * Real bummers unite ! 454359Sroberto * 554359Sroberto */ 654359Sroberto 754359Sroberto#ifdef HAVE_CONFIG_H 854359Sroberto#include "config.h" 954359Sroberto#endif 1054359Sroberto 1154359Sroberto#include "ntp_machine.h" 1254359Sroberto#include "ntp_syslog.h" 1354359Sroberto#include "ntp_stdlib.h" 1454359Sroberto#include "ntp_unixtime.h" 1554359Sroberto 1654359Sroberto#ifdef HAVE_UNISTD_H 1754359Sroberto#include <unistd.h> 1854359Sroberto#endif 1954359Sroberto 2054359Sroberto#ifdef SYS_WINNT 21132451Srobertoint _getch(void); /* Declare the one function rather than include conio.h */ 2254359Sroberto#else 2354359Sroberto 2454359Sroberto#ifdef SYS_VXWORKS 2554359Sroberto#include "taskLib.h" 2654359Sroberto#include "sysLib.h" 2754359Sroberto#include "time.h" 2854359Sroberto#include "ntp_syslog.h" 2954359Sroberto 3054359Sroberto/* some translations to the world of vxWorkings -casey */ 3154359Sroberto/* first some netdb type things */ 3254359Sroberto#include "ioLib.h" 3354359Sroberto#include <socket.h> 3454359Srobertoint h_errno; 3554359Sroberto 3654359Srobertostruct hostent *gethostbyname(char *name) 3754359Sroberto { 3854359Sroberto struct hostent *host1; 3954359Sroberto h_errno = 0; /* we are always successful!!! */ 4054359Sroberto host1 = (struct hostent *) malloc (sizeof(struct hostent)); 4154359Sroberto host1->h_name = name; 4254359Sroberto host1->h_addrtype = AF_INET; 4354359Sroberto host1->h_aliases = name; 4454359Sroberto host1->h_length = 4; 4554359Sroberto host1->h_addr_list[0] = (char *)hostGetByName (name); 4654359Sroberto host1->h_addr_list[1] = NULL; 4754359Sroberto return host1; 4854359Sroberto } 4954359Sroberto 5054359Srobertostruct hostent *gethostbyaddr(char *name, int size, int addr_type) 5154359Sroberto { 5254359Sroberto struct hostent *host1; 5354359Sroberto h_errno = 0; /* we are always successful!!! */ 5454359Sroberto host1 = (struct hostent *) malloc (sizeof(struct hostent)); 5554359Sroberto host1->h_name = name; 5654359Sroberto host1->h_addrtype = AF_INET; 5754359Sroberto host1->h_aliases = name; 5854359Sroberto host1->h_length = 4; 5954359Sroberto host1->h_addr_list = NULL; 6054359Sroberto return host1; 6154359Sroberto } 6254359Sroberto 6354359Srobertostruct servent *getservbyname (char *name, char *type) 6454359Sroberto { 6554359Sroberto struct servent *serv1; 6654359Sroberto serv1 = (struct servent *) malloc (sizeof(struct servent)); 6754359Sroberto serv1->s_name = "ntp"; /* official service name */ 6854359Sroberto serv1->s_aliases = NULL; /* alias list */ 6954359Sroberto serv1->s_port = 123; /* port # */ 7054359Sroberto serv1->s_proto = "udp"; /* protocol to use */ 7154359Sroberto return serv1; 7254359Sroberto } 7354359Sroberto 7454359Sroberto/* second 7554359Sroberto * vxworks thinks it has insomnia 7654359Sroberto * we have to sleep for number of seconds 7754359Sroberto */ 7854359Sroberto 7954359Sroberto#define CLKRATE sysClkRateGet() 8054359Sroberto 8154359Sroberto/* I am not sure how valid the granularity is - it is from G. Eger's port */ 8254359Sroberto#define CLK_GRANULARITY 1 /* Granularity of system clock in usec */ 8354359Sroberto /* Used to round down # usecs/tick */ 8454359Sroberto /* On a VCOM-100, PIT gets 8 MHz clk, */ 8554359Sroberto /* & it prescales by 32, thus 4 usec */ 8654359Sroberto /* on mv167, granularity is 1usec anyway*/ 8754359Sroberto /* To defeat rounding, set to 1 */ 8854359Sroberto#define USECS_PER_SEC MILLION /* Microseconds per second */ 8954359Sroberto#define TICK (((USECS_PER_SEC / CLKRATE) / CLK_GRANULARITY) * CLK_GRANULARITY) 9054359Sroberto 9154359Sroberto/* emulate unix sleep 9254359Sroberto * casey 9354359Sroberto */ 9454359Srobertovoid sleep(int seconds) 9554359Sroberto { 9654359Sroberto taskDelay(seconds*TICK); 9754359Sroberto } 9854359Sroberto/* emulate unix alarm 9954359Sroberto * that pauses and calls SIGALRM after the seconds are up... 10054359Sroberto * so ... taskDelay() fudged for seconds should amount to the same thing. 10154359Sroberto * casey 10254359Sroberto */ 10354359Srobertovoid alarm (int seconds) 10454359Sroberto { 10554359Sroberto sleep(seconds); 10654359Sroberto } 10754359Sroberto 10854359Sroberto#endif /* SYS_VXWORKS */ 10954359Sroberto 11054359Sroberto#ifdef SYS_PTX /* Does PTX still need this? */ 11154359Sroberto/*#include <sys/types.h> */ 11254359Sroberto#include <sys/procstats.h> 11354359Sroberto 11454359Srobertoint 11554359Srobertogettimeofday( 11654359Sroberto struct timeval *tvp 11754359Sroberto ) 11854359Sroberto{ 11954359Sroberto /* 12054359Sroberto * hi, this is Sequents sneak path to get to a clock 12154359Sroberto * this is also the most logical syscall for such a function 12254359Sroberto */ 12354359Sroberto return (get_process_stats(tvp, PS_SELF, (struct procstats *) 0, 12454359Sroberto (struct procstats *) 0)); 12554359Sroberto} 12654359Sroberto#endif /* SYS_PTX */ 12754359Sroberto 128106163Sroberto#ifdef MPE 129106163Sroberto/* This is a substitute for bind() that if called for an AF_INET socket 130106163Srobertoport less than 1024, GETPRIVMODE() and GETUSERMODE() calls will be done. */ 131106163Sroberto 132106163Sroberto#undef bind 133106163Sroberto#include <sys/types.h> 134106163Sroberto#include <sys/socket.h> 135106163Sroberto#include <netinet/in.h> 136106163Sroberto#include <sys/un.h> 137106163Sroberto 138106163Srobertoextern void GETPRIVMODE(void); 139106163Srobertoextern void GETUSERMODE(void); 140106163Sroberto 141106163Srobertoint __ntp_mpe_bind(int s, void *addr, int addrlen); 142106163Sroberto 143106163Srobertoint __ntp_mpe_bind(int s, void *addr, int addrlen) { 144106163Sroberto int priv = 0; 145106163Sroberto int result; 146106163Sroberto 147106163Srobertoif (addrlen == sizeof(struct sockaddr_in)) { /* AF_INET */ 148106163Sroberto if (((struct sockaddr_in *)addr)->sin_port > 0 && 149106163Sroberto ((struct sockaddr_in *)addr)->sin_port < 1024) { 150106163Sroberto priv = 1; 151106163Sroberto GETPRIVMODE(); 152106163Sroberto } 153106163Sroberto/* ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; */ 154106163Sroberto result = bind(s,addr,addrlen); 155106163Sroberto if (priv == 1) GETUSERMODE(); 156106163Sroberto} else /* AF_UNIX */ 157106163Sroberto result = bind(s,addr,addrlen); 158106163Sroberto 159106163Srobertoreturn result; 160106163Sroberto} 161106163Sroberto 162106163Sroberto/* 163106163Sroberto * MPE stupidly requires sfcntl() to be used on sockets instead of fcntl(), 164106163Sroberto * so we define a wrapper to analyze the file descriptor and call the correct 165106163Sroberto * function. 166106163Sroberto */ 167106163Sroberto 168106163Sroberto#undef fcntl 169106163Sroberto#include <errno.h> 170106163Sroberto#include <fcntl.h> 171106163Sroberto 172106163Srobertoint __ntp_mpe_fcntl(int fd, int cmd, int arg); 173106163Sroberto 174106163Srobertoint __ntp_mpe_fcntl(int fd, int cmd, int arg) { 175106163Sroberto int len; 176106163Sroberto struct sockaddr sa; 177106163Sroberto 178106163Sroberto extern int sfcntl(int, int, int); 179106163Sroberto 180106163Sroberto len = sizeof sa; 181106163Sroberto if (getsockname(fd, &sa, &len) == -1) { 182106163Sroberto if (errno == EAFNOSUPPORT) /* AF_UNIX socket */ 183106163Sroberto return sfcntl(fd, cmd, arg); 184106163Sroberto if (errno == ENOTSOCK) /* file or pipe */ 185106163Sroberto return fcntl(fd, cmd, arg); 186106163Sroberto return (-1); /* unknown getsockname() failure */ 187106163Sroberto } else /* AF_INET socket */ 188106163Sroberto return sfcntl(fd, cmd, arg); 189106163Sroberto} 190106163Sroberto 191106163Sroberto/* 192106163Sroberto * Setitimer emulation support. Note that we implement this using alarm(), 193106163Sroberto * and since alarm() only delivers one signal, we must re-enable the alarm 194106163Sroberto * by enabling our own SIGALRM setitimer_mpe_handler routine to be called 195106163Sroberto * before the real handler routine and re-enable the alarm at that time. 196106163Sroberto * 197106163Sroberto * Note that this solution assumes that sigaction(SIGALRM) is called before 198106163Sroberto * calling setitimer(). If it should ever to become necessary to support 199106163Sroberto * sigaction(SIGALRM) after calling setitimer(), it will be necessary to trap 200106163Sroberto * those sigaction() calls. 201106163Sroberto */ 202106163Sroberto 203106163Sroberto#include <limits.h> 204106163Sroberto#include <signal.h> 205106163Sroberto 206106163Sroberto/* 207106163Sroberto * Some global data that needs to be shared between setitimer() and 208106163Sroberto * setitimer_mpe_handler(). 209106163Sroberto */ 210106163Sroberto 211106163Srobertostruct { 212106163Sroberto unsigned long current_msec; /* current alarm() value in effect */ 213106163Sroberto unsigned long interval_msec; /* next alarm() value from setitimer */ 214106163Sroberto unsigned long value_msec; /* first alarm() value from setitimer */ 215106163Sroberto struct itimerval current_itimerval; /* current itimerval in effect */ 216106163Sroberto struct sigaction oldact; /* SIGALRM state saved by setitimer */ 217106163Sroberto} setitimer_mpe_ctx = { 0, 0, 0 }; 218106163Sroberto 219106163Sroberto/* 220106163Sroberto * Undocumented, unsupported function to do alarm() in milliseconds. 221106163Sroberto */ 222106163Sroberto 223106163Srobertoextern unsigned int px_alarm(unsigned long, int *); 224106163Sroberto 225106163Sroberto/* 226106163Sroberto * The SIGALRM handler routine enabled by setitimer(). Re-enable the alarm or 227106163Sroberto * restore the original SIGALRM setting if no more alarms are needed. Then 228106163Sroberto * call the original SIGALRM handler (if any). 229106163Sroberto */ 230106163Sroberto 231106163Srobertostatic RETSIGTYPE setitimer_mpe_handler(int sig) 232106163Sroberto{ 233106163Srobertoint alarm_hpe_status; 234106163Sroberto 235106163Sroberto/* Update the new current alarm value */ 236106163Sroberto 237106163Srobertosetitimer_mpe_ctx.current_msec = setitimer_mpe_ctx.interval_msec; 238106163Sroberto 239106163Srobertoif (setitimer_mpe_ctx.interval_msec > 0) { 240106163Sroberto /* Additional intervals needed; re-arm the alarm timer */ 241106163Sroberto px_alarm(setitimer_mpe_ctx.interval_msec,&alarm_hpe_status); 242106163Sroberto} else { 243106163Sroberto /* No more intervals, so restore previous original SIGALRM handler */ 244106163Sroberto sigaction(SIGALRM, &setitimer_mpe_ctx.oldact, NULL); 245106163Sroberto} 246106163Sroberto 247106163Sroberto/* Call the original SIGALRM handler if it is a function and not just a flag */ 248106163Sroberto 249106163Srobertoif (setitimer_mpe_ctx.oldact.sa_handler != SIG_DFL && 250106163Sroberto setitimer_mpe_ctx.oldact.sa_handler != SIG_ERR && 251106163Sroberto setitimer_mpe_ctx.oldact.sa_handler != SIG_IGN) 252106163Sroberto (*setitimer_mpe_ctx.oldact.sa_handler)(SIGALRM); 253106163Sroberto 254106163Sroberto} 255106163Sroberto 256106163Sroberto/* 257106163Sroberto * Our implementation of setitimer(). 258106163Sroberto */ 259106163Sroberto 260106163Srobertoint 261106163Srobertosetitimer(int which, struct itimerval *value, 262106163Sroberto struct itimerval *ovalue) 263106163Sroberto{ 264106163Sroberto 265106163Srobertoint alarm_hpe_status; 266106163Srobertounsigned long remaining_msec, value_msec, interval_msec; 267106163Srobertostruct sigaction newact; 268106163Sroberto 269106163Sroberto/* 270106163Sroberto * Convert the initial interval to milliseconds 271106163Sroberto */ 272106163Sroberto 273106163Srobertoif (value->it_value.tv_sec > (UINT_MAX / 1000)) 274106163Sroberto value_msec = UINT_MAX; 275106163Srobertoelse 276106163Sroberto value_msec = value->it_value.tv_sec * 1000; 277106163Sroberto 278106163Srobertovalue_msec += value->it_value.tv_usec / 1000; 279106163Sroberto 280106163Sroberto/* 281106163Sroberto * Convert the reset interval to milliseconds 282106163Sroberto */ 283106163Sroberto 284106163Srobertoif (value->it_interval.tv_sec > (UINT_MAX / 1000)) 285106163Sroberto interval_msec = UINT_MAX; 286106163Srobertoelse 287106163Sroberto interval_msec = value->it_interval.tv_sec * 1000; 288106163Sroberto 289106163Srobertointerval_msec += value->it_interval.tv_usec / 1000; 290106163Sroberto 291106163Srobertoif (value_msec > 0 && interval_msec > 0) { 292106163Sroberto /* 293106163Sroberto * We'll be starting an interval timer that will be repeating, so we need to 294106163Sroberto * insert our own SIGALRM signal handler to schedule the repeats. 295106163Sroberto */ 296106163Sroberto 297106163Sroberto /* Read the current SIGALRM action */ 298106163Sroberto 299106163Sroberto if (sigaction(SIGALRM, NULL, &setitimer_mpe_ctx.oldact) < 0) { 300106163Sroberto fprintf(stderr,"MPE setitimer old handler failed, errno=%d\n",errno); 301106163Sroberto return -1; 302106163Sroberto } 303106163Sroberto 304106163Sroberto /* Initialize the new action to call our SIGALRM handler instead */ 305106163Sroberto 306106163Sroberto newact.sa_handler = &setitimer_mpe_handler; 307106163Sroberto newact.sa_mask = setitimer_mpe_ctx.oldact.sa_mask; 308106163Sroberto newact.sa_flags = setitimer_mpe_ctx.oldact.sa_flags; 309106163Sroberto 310106163Sroberto if (sigaction(SIGALRM, &newact, NULL) < 0) { 311106163Sroberto fprintf(stderr,"MPE setitimer new handler failed, errno=%d\n",errno); 312106163Sroberto return -1; 313106163Sroberto } 314106163Sroberto} 315106163Sroberto 316106163Sroberto/* 317106163Sroberto * Return previous itimerval if desired 318106163Sroberto */ 319106163Sroberto 320106163Srobertoif (ovalue != NULL) *ovalue = setitimer_mpe_ctx.current_itimerval; 321106163Sroberto 322106163Sroberto/* 323106163Sroberto * Save current parameters for later usage 324106163Sroberto */ 325106163Sroberto 326106163Srobertosetitimer_mpe_ctx.current_itimerval = *value; 327106163Srobertosetitimer_mpe_ctx.current_msec = value_msec; 328106163Srobertosetitimer_mpe_ctx.value_msec = value_msec; 329106163Srobertosetitimer_mpe_ctx.interval_msec = interval_msec; 330106163Sroberto 331106163Sroberto/* 332106163Sroberto * Schedule the first alarm 333106163Sroberto */ 334106163Sroberto 335106163Srobertoremaining_msec = px_alarm(value_msec, &alarm_hpe_status); 336106163Srobertoif (alarm_hpe_status == 0) 337106163Sroberto return (0); 338106163Srobertoelse 339106163Sroberto return (-1); 340106163Sroberto} 341106163Sroberto 342106163Sroberto/* 343106163Sroberto * MPE lacks gettimeofday(), so we define our own. 344106163Sroberto */ 345106163Sroberto 346106163Srobertoint gettimeofday(struct timeval *tvp) 347106163Sroberto 348106163Sroberto{ 349106163Sroberto/* Documented, supported MPE functions. */ 350106163Srobertoextern void GETPRIVMODE(void); 351106163Srobertoextern void GETUSERMODE(void); 352106163Sroberto 353106163Sroberto/* Undocumented, unsupported MPE functions. */ 354106163Srobertoextern long long get_time(void); 355106163Srobertoextern void get_time_change_info(long long *, char *, char *); 356106163Srobertoextern long long ticks_to_micro(long long); 357106163Sroberto 358106163Srobertochar pwf_since_boot, recover_pwf_time; 359106163Srobertolong long mpetime, offset_ticks, offset_usec; 360106163Sroberto 361106163SrobertoGETPRIVMODE(); 362106163Srobertompetime = get_time(); /* MPE local time usecs since Jan 1 1970 */ 363106163Srobertoget_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time); 364106163Srobertooffset_usec = ticks_to_micro(offset_ticks); /* UTC offset usecs */ 365106163SrobertoGETUSERMODE(); 366106163Sroberto 367106163Srobertompetime = mpetime - offset_usec; /* Convert from local time to UTC */ 368106163Srobertotvp->tv_sec = mpetime / 1000000LL; 369106163Srobertotvp->tv_usec = mpetime % 1000000LL; 370106163Sroberto 371106163Srobertoreturn 0; 372106163Sroberto} 373106163Sroberto 374106163Sroberto/* 375106163Sroberto * MPE lacks settimeofday(), so we define our own. 376106163Sroberto */ 377106163Sroberto 378106163Sroberto#define HAVE_SETTIMEOFDAY 379106163Sroberto 380106163Srobertoint settimeofday(struct timeval *tvp) 381106163Sroberto 382106163Sroberto{ 383106163Sroberto/* Documented, supported MPE functions. */ 384106163Srobertoextern void GETPRIVMODE(void); 385106163Srobertoextern void GETUSERMODE(void); 386106163Sroberto 387106163Sroberto/* Undocumented, unsupported MPE functions. */ 388106163Srobertoextern void get_time_change_info(long long *, char *, char *); 389106163Srobertoextern void initialize_system_time(long long, int); 390106163Srobertoextern void set_time_correction(long long, int, int); 391106163Srobertoextern long long ticks_to_micro(long long); 392106163Sroberto 393106163Srobertochar pwf_since_boot, recover_pwf_time; 394106163Srobertolong long big_sec, big_usec, mpetime, offset_ticks, offset_usec; 395106163Sroberto 396106163Srobertobig_sec = tvp->tv_sec; 397106163Srobertobig_usec = tvp->tv_usec; 398106163Srobertompetime = (big_sec * 1000000LL) + big_usec; /* Desired UTC microseconds */ 399106163Sroberto 400106163SrobertoGETPRIVMODE(); 401106163Srobertoset_time_correction(0LL,0,0); /* Cancel previous time correction, if any */ 402106163Srobertoget_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time); 403106163Srobertooffset_usec = ticks_to_micro(offset_ticks); /* UTC offset microseconds */ 404106163Srobertompetime = mpetime + offset_usec; /* Convert from UTC to local time */ 405106163Srobertoinitialize_system_time(mpetime,1); 406106163SrobertoGETUSERMODE(); 407106163Sroberto 408106163Srobertoreturn 0; 409106163Sroberto} 410106163Sroberto#endif /* MPE */ 411106163Sroberto 41254359Srobertoconst char *set_tod_using = "UNKNOWN"; 41354359Sroberto 41454359Srobertoint 41554359Srobertontp_set_tod( 41654359Sroberto struct timeval *tvp, 41754359Sroberto void *tzp 41854359Sroberto ) 41954359Sroberto{ 420106163Sroberto int rc = -1; 42154359Sroberto 422106163Sroberto#ifdef DEBUG 423106163Sroberto if (debug) 424106163Sroberto printf("In ntp_set_tod\n"); 425106163Sroberto#endif 426106163Sroberto 42754359Sroberto#ifdef HAVE_CLOCK_SETTIME 428106163Sroberto if (rc) { 42954359Sroberto struct timespec ts; 43054359Sroberto 431106163Sroberto set_tod_using = "clock_settime"; 43254359Sroberto /* Convert timeval to timespec */ 43354359Sroberto ts.tv_sec = tvp->tv_sec; 43454359Sroberto ts.tv_nsec = 1000 * tvp->tv_usec; 43554359Sroberto 436106163Sroberto errno = 0; 43754359Sroberto rc = clock_settime(CLOCK_REALTIME, &ts); 438106163Sroberto#ifdef DEBUG 439106163Sroberto if (debug) { 440106163Sroberto printf("ntp_set_tod: %s: %d: %s\n", 441106163Sroberto set_tod_using, rc, strerror(errno)); 44254359Sroberto } 443106163Sroberto#endif 44454359Sroberto } 44554359Sroberto#endif /* HAVE_CLOCK_SETTIME */ 44654359Sroberto#ifdef HAVE_SETTIMEOFDAY 447106163Sroberto if (rc) { 448132451Sroberto struct timeval adjtv; 449132451Sroberto 450106163Sroberto set_tod_using = "settimeofday"; 451132451Sroberto /* 452132451Sroberto * Some broken systems don't reset adjtime() when the 453132451Sroberto * clock is stepped. 454132451Sroberto */ 455132451Sroberto adjtv.tv_sec = adjtv.tv_usec = 0; 456132451Sroberto adjtime(&adjtv, NULL); 457182007Sroberto errno = 0; 45854359Sroberto rc = SETTIMEOFDAY(tvp, tzp); 459106163Sroberto#ifdef DEBUG 460106163Sroberto if (debug) { 461106163Sroberto printf("ntp_set_tod: %s: %d: %s\n", 462106163Sroberto set_tod_using, rc, strerror(errno)); 46354359Sroberto } 464106163Sroberto#endif 46554359Sroberto } 46654359Sroberto#endif /* HAVE_SETTIMEOFDAY */ 46754359Sroberto#ifdef HAVE_STIME 468106163Sroberto if (rc) { 46954359Sroberto long tp = tvp->tv_sec; 47054359Sroberto 471106163Sroberto set_tod_using = "stime"; 472182007Sroberto errno = 0; 47354359Sroberto rc = stime(&tp); /* lie as bad as SysVR4 */ 474106163Sroberto#ifdef DEBUG 475106163Sroberto if (debug) { 476106163Sroberto printf("ntp_set_tod: %s: %d: %s\n", 477106163Sroberto set_tod_using, rc, strerror(errno)); 47854359Sroberto } 479106163Sroberto#endif 48054359Sroberto } 48154359Sroberto#endif /* HAVE_STIME */ 482106163Sroberto if (rc) 483106163Sroberto set_tod_using = "Failed!"; 484106163Sroberto#ifdef DEBUG 485106163Sroberto if (debug) { 486106163Sroberto printf("ntp_set_tod: Final result: %s: %d: %s\n", 487106163Sroberto set_tod_using, rc, strerror(errno)); 488106163Sroberto } 489106163Sroberto#endif 490106163Sroberto return rc; 49154359Sroberto} 49254359Sroberto 49354359Sroberto#endif /* not SYS_WINNT */ 49454359Sroberto 495106163Sroberto#if defined (SYS_WINNT) || defined (SYS_VXWORKS) || defined(MPE) 49654359Sroberto/* getpass is used in ntpq.c and ntpdc.c */ 49754359Sroberto 49854359Srobertochar * 49954359Srobertogetpass(const char * prompt) 50054359Sroberto{ 50154359Sroberto int c, i; 50254359Sroberto static char password[32]; 503182007Sroberto 50454359Sroberto fprintf(stderr, "%s", prompt); 50554359Sroberto fflush(stderr); 506182007Sroberto 50782498Sroberto for (i=0; i<sizeof(password)-1 && ((c=_getch())!='\n' && c!='\r'); i++) { 50854359Sroberto password[i] = (char) c; 50954359Sroberto } 51054359Sroberto password[i] = '\0'; 51154359Sroberto 51254359Sroberto return password; 51354359Sroberto} 51454359Sroberto#endif /* SYS_WINNT */ 51554359Sroberto 51654359Sroberto#if !defined(HAVE_MEMSET) 51754359Srobertovoid 51854359Srobertontp_memset( 51954359Sroberto char *a, 52054359Sroberto int x, 52154359Sroberto int c 52254359Sroberto ) 52354359Sroberto{ 52454359Sroberto while (c-- > 0) 52554359Sroberto *a++ = (char) x; 52654359Sroberto} 52754359Sroberto#endif /*POSIX*/ 528