/*---------------------------------------------------------------------------*/ void cc26xx_uart_isr(void) { char the_char; uint32_t flags; ENERGEST_ON(ENERGEST_TYPE_IRQ); power_and_clock(); /* Read out the masked interrupt status */ flags = ti_lib_uart_int_status(UART0_BASE, true); /* Clear all UART interrupt flags */ ti_lib_uart_int_clear(UART0_BASE, CC26XX_UART_INTERRUPT_ALL); if((flags & CC26XX_UART_RX_INTERRUPT_TRIGGERS) != 0) { /* * If this was a FIFO RX or an RX timeout, read all bytes available in the * RX FIFO. */ while(ti_lib_uart_chars_avail(UART0_BASE)) { the_char = ti_lib_uart_char_get_non_blocking(UART0_BASE); if(input_handler != NULL) { input_handler((unsigned char)the_char); } } } ENERGEST_OFF(ENERGEST_TYPE_IRQ); }
/*---------------------------------------------------------------------------*/ void uart_isr(void) { uint16_t mis; ENERGEST_ON(ENERGEST_TYPE_IRQ); /* Store the current MIS and clear all flags early, except the RTM flag. * This will clear itself when we read out the entire FIFO contents */ mis = REG(UART_BASE | UART_MIS) & 0x0000FFFF; REG(UART_BASE | UART_ICR) = 0x0000FFBF; if(mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) { while(!(REG(UART_BASE | UART_FR) & UART_FR_RXFE)) { if(input_handler != NULL) { input_handler((unsigned char)(REG(UART_BASE | UART_DR) & 0xFF)); } else { /* To prevent an Overrun Error, we need to flush the FIFO even if we * don't have an input_handler. Use mis as a data trash can */ mis = REG(UART_BASE | UART_DR); } } } else if(mis & (UART_MIS_OEMIS | UART_MIS_BEMIS | UART_MIS_FEMIS)) { /* ISR triggered due to some error condition */ reset(); } ENERGEST_OFF(ENERGEST_TYPE_IRQ); }
static void serial_input_handler(struct serial_binding *b, char *data, size_t size) { struct pc16550d *state = b->st; input_handler(state, data, size); }
/* --------------------------------------------------------------- */ PROCESS_THREAD(node_process, ev, data) { // All the process start with this PROCESS_BEGIN(); PRINTF("# Starting...\n"); // Configure the network network_config(); if (!conn) { printf("E01\n"); PROCESS_EXIT(); } #if IS_RPL_ROOT create_dag(); #endif // Main, infinite, loop of the process PRINTF("# Ready!\n"); while (1) { // Wait, block the process, until an event happens. // Meanwhile, other process will continue running. PROCESS_WAIT_EVENT(); // Check the type of event that unblock the process if (ev == tcpip_event) tcpip_handler(); else if (ev == serial_line_event_message) input_handler((char*)data); } // All the process ends with this PROCESS_END(); }
/*---------------------------------------------------------------------------*/ void uart_isr(void) { uint16_t mis; ENERGEST_ON(ENERGEST_TYPE_IRQ); /* Store the current MIS and clear all flags early, except the RTM flag. * This will clear itself when we read out the entire FIFO contents */ mis = (uint16_t)UARTIntStatus(UART0_BASE, true); HWREG(UART0_BASE | UART_O_ICR) = 0x0000FFBF; if(mis & (UART_INT_RX | UART_INT_RT)) { if(input_handler != NULL) { input_handler((unsigned char)UARTCharGetNonBlocking(UART0_BASE)); } else { /* To prevent an Overrun Error, we need to flush the FIFO even if we * don't have an input_handler. Use mis as a data trash can */ mis = (uint16_t)UARTCharGetNonBlocking(UART0_BASE); } } else if(mis & (UART_INT_OE | UART_INT_BE | UART_INT_FE)) { /* ISR triggered due to some error condition */ reset(); } ENERGEST_OFF(ENERGEST_TYPE_IRQ); }
RETSIGTYPE sigio_handler( int sig ) { int saved_errno = errno; l_fp ts; get_systime(&ts); # if defined(HAVE_SIGACTION) sigio_handler_active++; if (sigio_handler_active != 1) /* This should never happen! */ msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1"); # endif (void)input_handler(&ts); # if defined(HAVE_SIGACTION) sigio_handler_active--; if (sigio_handler_active != 0) /* This should never happen! */ msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0"); # endif errno = saved_errno; }
/*-----------------------------------------------------------------------------------*/ static void doInterfaceActionsBeforeTick(void) { int i; if (!simSerialReceivingFlag) { return; } if (simSerialReceivingLength == 0) { /* Error, should not be zero */ simSerialReceivingFlag = 0; return; } /* Notify specified rs232 handler */ if(input_handler != NULL) { for (i=0; i < simSerialReceivingLength; i++) { input_handler(simSerialReceivingData[i]); } } else { /* Notify serial process */ for (i=0; i < simSerialReceivingLength; i++) { serial_line_input_byte(simSerialReceivingData[i]); } serial_line_input_byte(0x0a); } simSerialReceivingLength = 0; simSerialReceivingFlag = 0; }
int main(int argc, char* argv[]) { state_st state = {0}; // set locale, otherwise we cant use unicode characters for the walls setlocale(LC_ALL, ""); // seed random # srand(time(NULL)); // check for logging if (argc > 1) { if (!strcmp(argv[1], "--debug")) { logger_set_level(LOGGER_LEVEL_DEBUG); } else if (!strcmp(argv[1], "--verbose")) { logger_set_level(LOGGER_LEVEL_VERBOSE); } else if (!strcmp(argv[1], "--warn")) { logger_set_level(LOGGER_LEVEL_WARN); } else if (!strcmp(argv[1], "--error")) { logger_set_level(LOGGER_LEVEL_ERROR); } } // set up logger. If no level has been set this call will do nothing. logger_init(); // set up game state game_init(&state); // welcome screen. get rogue's name, roll rogue welcome(&state); // game loop do { // draw draw(&state); // input input_handler(&state); } while(state.running); endwin(); free_state(&state); logger_stop(); return (EXIT_SUCCESS); }
/*---------------------------------------------------------------------------*/ static void do_work(void) { unsigned int events; events = usb_get_global_events(); if(events & USB_EVENT_CONFIG) { /* Configure EPs. Don't enable them yet, until the CDC line is up */ usb_setup_bulk_endpoint(EPIN); usb_setup_bulk_endpoint(EPOUT); queue_rx_urb(); } if(events & USB_EVENT_RESET) { enabled = 0; } events = usb_cdc_acm_get_events(); if(events & USB_CDC_ACM_LINE_STATE) { uint8_t line_state = usb_cdc_acm_get_line_state(); PRINTF("CDC-ACM event 0x%04x, Line State = %u\n", events, line_state); if(line_state & USB_CDC_ACM_DTE) { enabled = 1; } else { enabled = 0; } } if(!enabled) { return; } events = usb_get_ep_events(EPOUT); if((events & USB_EP_EVENT_NOTIFICATION) && !(data_rx_urb.flags & USB_BUFFER_SUBMITTED)) { if(!(data_rx_urb.flags & USB_BUFFER_FAILED)) { if(input_handler) { uint8_t len; uint8_t i; len = RX_BUFFER_SIZE - data_rx_urb.left; for(i = 0; i < len; i++) { input_handler(usb_rx_data[i]); } } } queue_rx_urb(); } }
int main (void) { state = 1; // Initialize State pressed = 0; // Make sure pressed is clear SystemCoreClockUpdate(); /* Get Core Clock Frequency */ if (SysTick_Config(SystemCoreClock / 1000 )) { /* SysTick 1 msec interrupts */ while (1); /* Capture error */ } /* Initialize the LEDS and the buttons */ LED_Init(); BTN_Init(); for (;;) { // loop forever input_handler(); // call input_handler } }
/* * Main program. Initialize us, disconnect us from the tty if necessary, * and loop waiting for I/O and/or timer expiries. */ int ntpdmain( int argc, char *argv[] ) { l_fp now; struct recvbuf *rbuf; #ifdef _AIX /* HMS: ifdef SIGDANGER? */ struct sigaction sa; #endif progname = argv[0]; initializing = 1; /* mark that we are initializing */ process_commandline_opts(&argc, &argv); init_logging(progname, 1); /* Open the log file */ char *error = NULL; if (sandbox_init("ntpd", SANDBOX_NAMED, &error) == -1) { msyslog(LOG_ERR, "sandbox_init(ntpd, SANDBOX_NAMED) failed: %s", error); sandbox_free_error(error); } #ifdef HAVE_UMASK { mode_t uv; uv = umask(0); if(uv) (void) umask(uv); else (void) umask(022); } #endif #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ { uid_t uid; uid = getuid(); if (uid && !HAVE_OPT( SAVECONFIGQUIT )) { msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid); printf("must be run as root, not uid %ld\n", (long)uid); exit(1); } } #endif /* getstartup(argc, argv); / * startup configuration, may set debug */ #ifdef DEBUG debug = DESC(DEBUG_LEVEL).optOccCt; DPRINTF(1, ("%s\n", Version)); #endif /* honor -l/--logfile option to log to a file */ setup_logfile(); /* * Enable the Multi-Media Timer for Windows? */ #ifdef SYS_WINNT if (HAVE_OPT( MODIFYMMTIMER )) set_mm_timer(MM_TIMER_HIRES); #endif if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT ) #ifdef DEBUG || debug #endif || HAVE_OPT( SAVECONFIGQUIT )) nofork = 1; if (HAVE_OPT( NOVIRTUALIPS )) listen_to_virtual_ips = 0; /* * --interface, listen on specified interfaces */ if (HAVE_OPT( INTERFACE )) { int ifacect = STACKCT_OPT( INTERFACE ); const char** ifaces = STACKLST_OPT( INTERFACE ); isc_netaddr_t netaddr; while (ifacect-- > 0) { add_nic_rule( is_ip_address(*ifaces, &netaddr) ? MATCH_IFADDR : MATCH_IFNAME, *ifaces, -1, ACTION_LISTEN); ifaces++; } } if (HAVE_OPT( NICE )) priority_done = 0; #if defined(HAVE_SCHED_SETSCHEDULER) if (HAVE_OPT( PRIORITY )) { config_priority = OPT_VALUE_PRIORITY; config_priority_override = 1; priority_done = 0; } #endif #ifdef SYS_WINNT /* * Start interpolation thread, must occur before first * get_systime() */ init_winnt_time(); #endif /* * Initialize random generator and public key pair */ get_systime(&now); ntp_srandom((int)(now.l_i * now.l_uf)); #if !defined(VMS) # ifndef NODETACH /* * Detach us from the terminal. May need an #ifndef GIZMO. */ if (!nofork) { /* * Install trap handlers to log errors and assertion * failures. Default handlers print to stderr which * doesn't work if detached. */ isc_assertion_setcallback(assertion_failed); isc_error_setfatal(library_fatal_error); isc_error_setunexpected(library_unexpected_error); # ifndef SYS_WINNT # ifdef HAVE_DAEMON daemon(0, 0); # else /* not HAVE_DAEMON */ if (fork()) /* HMS: What about a -1? */ exit(0); { #if !defined(F_CLOSEM) u_long s; int max_fd; #endif /* !FCLOSEM */ if (syslog_file != NULL) { fclose(syslog_file); syslog_file = NULL; } #if defined(F_CLOSEM) /* * From 'Writing Reliable AIX Daemons,' SG24-4946-00, * by Eric Agar (saves us from doing 32767 system * calls) */ if (fcntl(0, F_CLOSEM, 0) == -1) msyslog(LOG_ERR, "ntpd: failed to close open files(): %m"); #else /* not F_CLOSEM */ # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) max_fd = sysconf(_SC_OPEN_MAX); # else /* HAVE_SYSCONF && _SC_OPEN_MAX */ max_fd = getdtablesize(); # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */ for (s = 0; s < max_fd; s++) (void) close((int)s); #endif /* not F_CLOSEM */ (void) open("/", 0); (void) dup2(0, 1); (void) dup2(0, 2); init_logging(progname, 0); /* we lost our logfile (if any) daemonizing */ setup_logfile(); #ifdef SYS_DOMAINOS { uid_$t puid; status_$t st; proc2_$who_am_i(&puid); proc2_$make_server(&puid, &st); } #endif /* SYS_DOMAINOS */ #if defined(HAVE_SETPGID) || defined(HAVE_SETSID) # ifdef HAVE_SETSID if (setsid() == (pid_t)-1) msyslog(LOG_ERR, "ntpd: setsid(): %m"); # else if (setpgid(0, 0) == -1) msyslog(LOG_ERR, "ntpd: setpgid(): %m"); # endif #else /* HAVE_SETPGID || HAVE_SETSID */ { # if defined(TIOCNOTTY) int fid; fid = open("/dev/tty", 2); if (fid >= 0) { (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0); (void) close(fid); } # endif /* defined(TIOCNOTTY) */ # ifdef HAVE_SETPGRP_0 (void) setpgrp(); # else /* HAVE_SETPGRP_0 */ (void) setpgrp(0, getpid()); # endif /* HAVE_SETPGRP_0 */ } #endif /* HAVE_SETPGID || HAVE_SETSID */ #ifdef _AIX /* Don't get killed by low-on-memory signal. */ sa.sa_handler = catch_danger; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; (void) sigaction(SIGDANGER, &sa, NULL); #endif /* _AIX */ } # endif /* not HAVE_DAEMON */ # endif /* SYS_WINNT */ } # endif /* NODETACH */ #endif /* VMS */ #ifdef SCO5_CLOCK /* * SCO OpenServer's system clock offers much more precise timekeeping * on the base CPU than the other CPUs (for multiprocessor systems), * so we must lock to the base CPU. */ { int fd = open("/dev/at1", O_RDONLY); if (fd >= 0) { int zero = 0; if (ioctl(fd, ACPU_LOCK, &zero) < 0) msyslog(LOG_ERR, "cannot lock to base CPU: %m"); close( fd ); } /* else ... * If we can't open the device, this probably just isn't * a multiprocessor system, so we're A-OK. */ } #endif #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE) # ifdef HAVE_SETRLIMIT /* * Set the stack limit to something smaller, so that we don't lock a lot * of unused stack memory. */ { struct rlimit rl; /* HMS: must make the rlim_cur amount configurable */ if (getrlimit(RLIMIT_STACK, &rl) != -1 && (rl.rlim_cur = 50 * 4096) < rl.rlim_max) { if (setrlimit(RLIMIT_STACK, &rl) == -1) { msyslog(LOG_ERR, "Cannot adjust stack limit for mlockall: %m"); } } # ifdef RLIMIT_MEMLOCK /* * The default RLIMIT_MEMLOCK is very low on Linux systems. * Unless we increase this limit malloc calls are likely to * fail if we drop root privlege. To be useful the value * has to be larger than the largest ntpd resident set size. */ rl.rlim_cur = rl.rlim_max = 32*1024*1024; if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) { msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m"); } # endif /* RLIMIT_MEMLOCK */ } # endif /* HAVE_SETRLIMIT */ /* * lock the process into memory */ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) msyslog(LOG_ERR, "mlockall(): %m"); #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ # ifdef HAVE_PLOCK # ifdef PROCLOCK # ifdef _AIX /* * set the stack limit for AIX for plock(). * see get_aix_stack() for more info. */ if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0) { msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m"); } # endif /* _AIX */ /* * lock the process into memory */ if (plock(PROCLOCK) < 0) msyslog(LOG_ERR, "plock(PROCLOCK): %m"); # else /* not PROCLOCK */ # ifdef TXTLOCK /* * Lock text into ram */ if (plock(TXTLOCK) < 0) msyslog(LOG_ERR, "plock(TXTLOCK) error: %m"); # else /* not TXTLOCK */ msyslog(LOG_ERR, "plock() - don't know what to lock!"); # endif /* not TXTLOCK */ # endif /* not PROCLOCK */ # endif /* HAVE_PLOCK */ #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ /* * Set up signals we pay attention to locally. */ #ifdef SIGDIE1 (void) signal_no_reset(SIGDIE1, finish); #endif /* SIGDIE1 */ #ifdef SIGDIE2 (void) signal_no_reset(SIGDIE2, finish); #endif /* SIGDIE2 */ #ifdef SIGDIE3 (void) signal_no_reset(SIGDIE3, finish); #endif /* SIGDIE3 */ #ifdef SIGDIE4 (void) signal_no_reset(SIGDIE4, finish); #endif /* SIGDIE4 */ #ifdef SIGBUS (void) signal_no_reset(SIGBUS, finish); #endif /* SIGBUS */ #if !defined(SYS_WINNT) && !defined(VMS) # ifdef DEBUG (void) signal_no_reset(MOREDEBUGSIG, moredebug); (void) signal_no_reset(LESSDEBUGSIG, lessdebug); # else (void) signal_no_reset(MOREDEBUGSIG, no_debug); (void) signal_no_reset(LESSDEBUGSIG, no_debug); # endif /* DEBUG */ #endif /* !SYS_WINNT && !VMS */ /* * Set up signals we should never pay attention to. */ #if defined SIGPIPE (void) signal_no_reset(SIGPIPE, SIG_IGN); #endif /* SIGPIPE */ /* * Call the init_ routines to initialize the data structures. * * Exactly what command-line options are we expecting here? */ init_auth(); init_util(); init_restrict(); init_mon(); init_timer(); init_lib(); init_request(); init_control(); init_peer(); #ifdef REFCLOCK init_refclock(); #endif set_process_priority(); init_proto(); /* Call at high priority */ init_io(); init_loopfilter(); mon_start(MON_ON); /* monitor on by default now */ /* turn off in config if unwanted */ /* * Get the configuration. This is done in a separate module * since this will definitely be different for the gizmo board. */ getconfig(argc, argv); NLOG(NLOG_SYSINFO) /* 'if' clause for syslog */ msyslog(LOG_NOTICE, "%s", Version); report_event(EVNT_SYSRESTART, NULL, NULL); loop_config(LOOP_DRIFTCOMP, old_drift); initializing = 0; #ifdef HAVE_DROPROOT if( droproot ) { /* Drop super-user privileges and chroot now if the OS supports this */ #ifdef HAVE_LINUX_CAPABILITIES /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */ if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) { msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" ); exit(-1); } #else /* we need a user to switch to */ if (user == NULL) { msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" ); exit(-1); } #endif /* HAVE_LINUX_CAPABILITIES */ if (user != NULL) { if (isdigit((unsigned char)*user)) { sw_uid = (uid_t)strtoul(user, &endp, 0); if (*endp != '\0') goto getuser; if ((pw = getpwuid(sw_uid)) != NULL) { user = strdup(pw->pw_name); if (NULL == user) { msyslog(LOG_ERR, "strdup() failed: %m"); exit (-1); } sw_gid = pw->pw_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find user ID %s", user); exit (-1); } } else { getuser: errno = 0; if ((pw = getpwnam(user)) != NULL) { sw_uid = pw->pw_uid; sw_gid = pw->pw_gid; } else { if (errno) msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user); else msyslog(LOG_ERR, "Cannot find user `%s'", user); exit (-1); } } } if (group != NULL) { if (isdigit((unsigned char)*group)) { sw_gid = (gid_t)strtoul(group, &endp, 0); if (*endp != '\0') goto getgroup; } else { getgroup: if ((gr = getgrnam(group)) != NULL) { sw_gid = gr->gr_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find group `%s'", group); exit (-1); } } } if (chrootdir ) { /* make sure cwd is inside the jail: */ if (chdir(chrootdir)) { msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir); exit (-1); } if (chroot(chrootdir)) { msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir); exit (-1); } if (chdir("/")) { msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m"); exit (-1); } } if (user && initgroups(user, sw_gid)) { msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user); exit (-1); } if (group && setgid(sw_gid)) { msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group); exit (-1); } if (group && setegid(sw_gid)) { msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group); exit (-1); } if (user && setuid(sw_uid)) { msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user); exit (-1); } if (user && seteuid(sw_uid)) { msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user); exit (-1); } #ifndef HAVE_LINUX_CAPABILITIES /* * for now assume that the privilege to bind to privileged ports * is associated with running with uid 0 - should be refined on * ports that allow binding to NTP_PORT with uid != 0 */ disable_dynamic_updates |= (sw_uid != 0); /* also notifies routing message listener */ #endif if (disable_dynamic_updates && interface_interval) { interface_interval = 0; msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking"); } #ifdef HAVE_LINUX_CAPABILITIES do { /* * We may be running under non-root uid now, but we still hold full root privileges! * We drop all of them, except for the crucial one or two: cap_sys_time and * cap_net_bind_service if doing dynamic interface tracking. */ cap_t caps; char *captext = (interface_interval) ? "cap_sys_time,cap_net_bind_service=ipe" : "cap_sys_time=ipe"; if( ! ( caps = cap_from_text( captext ) ) ) { msyslog( LOG_ERR, "cap_from_text() failed: %m" ); exit(-1); } if( cap_set_proc( caps ) == -1 ) { msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" ); exit(-1); } cap_free( caps ); } while(0); #endif /* HAVE_LINUX_CAPABILITIES */ } /* if( droproot ) */ #endif /* HAVE_DROPROOT */ /* * Use select() on all on all input fd's for unlimited * time. select() will terminate on SIGALARM or on the * reception of input. Using select() means we can't do * robust signal handling and we get a potential race * between checking for alarms and doing the select(). * Mostly harmless, I think. */ /* On VMS, I suspect that select() can't be interrupted * by a "signal" either, so I take the easy way out and * have select() time out after one second. * System clock updates really aren't time-critical, * and - lacking a hardware reference clock - I have * yet to learn about anything else that is. */ #if defined(HAVE_IO_COMPLETION_PORT) for (;;) { GetReceivedBuffers(); #else /* normal I/O */ BLOCK_IO_AND_ALARM(); was_alarmed = 0; for (;;) { # if !defined(HAVE_SIGNALED_IO) extern fd_set activefds; extern int maxactivefd; fd_set rdfdes; int nfound; # endif if (alarm_flag) /* alarmed? */ { was_alarmed = 1; alarm_flag = 0; } if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE) { /* * Nothing to do. Wait for something. */ # ifndef HAVE_SIGNALED_IO rdfdes = activefds; # if defined(VMS) || defined(SYS_VXWORKS) /* make select() wake up after one second */ { struct timeval t1; t1.tv_sec = 1; t1.tv_usec = 0; nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, &t1); } # else nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, (struct timeval *)0); # endif /* VMS */ if (nfound > 0) { l_fp ts; get_systime(&ts); (void)input_handler(&ts); } else if (nfound == -1 && errno != EINTR) msyslog(LOG_ERR, "select() error: %m"); # ifdef DEBUG else if (debug > 5) msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound); # endif /* DEBUG */ # else /* HAVE_SIGNALED_IO */ wait_for_signal(); # endif /* HAVE_SIGNALED_IO */ if (alarm_flag) /* alarmed? */ { was_alarmed = 1; alarm_flag = 0; } } if (was_alarmed) { UNBLOCK_IO_AND_ALARM(); /* * Out here, signals are unblocked. Call timer routine * to process expiry. */ timer(); was_alarmed = 0; BLOCK_IO_AND_ALARM(); } #endif /* ! HAVE_IO_COMPLETION_PORT */ #ifdef DEBUG_TIMING { l_fp pts; l_fp tsa, tsb; int bufcount = 0; get_systime(&pts); tsa = pts; #endif rbuf = get_full_recv_buffer(); while (rbuf != NULL) { if (alarm_flag) { was_alarmed = 1; alarm_flag = 0; } UNBLOCK_IO_AND_ALARM(); if (was_alarmed) { /* avoid timer starvation during lengthy I/O handling */ timer(); was_alarmed = 0; } /* * Call the data procedure to handle each received * packet. */ if (rbuf->receiver != NULL) /* This should always be true */ { #ifdef DEBUG_TIMING l_fp dts = pts; L_SUB(&dts, &rbuf->recv_time); DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9))); collect_timing(rbuf, "buffer processing delay", 1, &dts); bufcount++; #endif (rbuf->receiver)(rbuf); } else { msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING"); abort(); } BLOCK_IO_AND_ALARM(); freerecvbuf(rbuf); rbuf = get_full_recv_buffer(); } #ifdef DEBUG_TIMING get_systime(&tsb); L_SUB(&tsb, &tsa); if (bufcount) { collect_timing(NULL, "processing", bufcount, &tsb); DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9))); } } #endif /* * Go around again */ #ifdef HAVE_DNSREGISTRATION if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) { mdnsreg = current_time; msyslog(LOG_INFO, "Attemping to register mDNS"); if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) { if (!--mdnstries) { msyslog(LOG_ERR, "Unable to register mDNS, giving up."); } else { msyslog(LOG_INFO, "Unable to register mDNS, will try later."); } } else { msyslog(LOG_INFO, "mDNS service registered."); mdnsreg = 0; } } #endif /* HAVE_DNSREGISTRATION */ } UNBLOCK_IO_AND_ALARM(); return 1; } #ifdef SIGDIE2 /* * finish - exit gracefully */ static RETSIGTYPE finish( int sig ) { msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig); #ifdef HAVE_DNSREGISTRATION if (mdns != NULL) DNSServiceRefDeallocate(mdns); #endif switch (sig) { # ifdef SIGBUS case SIGBUS: printf("\nfinish(SIGBUS)\n"); exit(0); # endif case 0: /* Should never happen... */ return; default: exit(0); } }
/****************************************************************************** * * main * *****************************************************************************/ int main ( int argc, char **argv ) { char **cmdLine; int success; fd_set readfds, exceptfds; int nfound; struct timeval timeoutShort, timeoutLong; int junki,i; char *tmpBuffer; int errorBytes; int firstPass, tmpi; char *tmpProgName = NULL; setlocale( LC_ALL, "" ); #ifdef _DTEXEC_NLS16 Dt_nlInit(); #endif /* _DTEXEC_NLS16 */ /* * For debugging purposes, a way to pause the process and allow * time for a xdb -P debugger attach. If no args, (e.g. libDtSvc is * test running the executable), cruise on. */ if (getenv("_DTEXEC_DEBUG") && (argc > 1)) { /* * Don't block in a system call, or on libDtSvc's attempts to * just test exec us. */ SPINBLOCK } /* * Note: dtSvcProcIdG is used like a boolean to control whether * we are communicating with libDtSvc using Tooltalk. */ dtSvcProcIdG = (char *) NULL; /* assume not communicating with TT */ ttfdG = -1; cmdLine = ParseCommandLine (argc, argv); /* * If a signal goes off *outside* the upcoming select, we'll need to * rediscover the signal by letting select() timeout. * * We might also set a rediscover flag to fake a signal response. */ rediscoverSigCldG = 0; /* boolean and counter */ rediscoverUrgentSigG = 0; /* boolean and counter */ InitializeSignalHandling (); /* * Create a pipe for logging of errors for actions without * windows. */ errorpipeG[0] = -1; /* by default, no stderr redirection */ errorpipeG[1] = -1; if ( requestTypeG == TRANSIENT ) { /* should be WINDOW_TYPE NO_STDIO */ if ( pipe(errorpipeG) == -1 ) { errorpipeG[0] = -1; errorpipeG[1] = -1; } } if (cmdLine) { success = ExecuteCommand (cmdLine); if (!success) { /* * Act like we were killed - it will result in a * DtACTION_FAILED. */ childPidG = -1; rediscoverUrgentSigG = 1; } } else { /* * Act like we had a child and it went away - it will result * in a DtACTION_DONE. */ childPidG = -1; rediscoverSigCldG = 1; } /* * Note when we started so we can compare times when we finish. */ (void) gettimeofday (&startTimeG, &zoneG); if (dtSvcProcIdG) { if ( !InitializeTooltalk() ) { /* * We have no hope of talking to our caller via Tooltalk. */ dtSvcProcIdG = (char *) NULL; } } /* * Tie in to the default session and start chatting. */ if (dtSvcProcIdG) tt_session_join(tt_default_session()); /* * Finally send caller our current proc id so they can talk back. */ if (dtSvcProcIdG) IdSelfToCallerRequest(); /* * Monitor file descriptors for activity. If errors occur on a fds, * it will be removed from allactivefdsG after handling the error. */ CLEARBITS(allactivefdsG); /* * Add Tooltalk */ if ( ttfdG != -1 ) BITSET(allactivefdsG, ttfdG); /* add Tooltalk */ /* * Add Error Log */ if ( errorpipeG[0] != -1 ) BITSET(allactivefdsG, errorpipeG[0]); /* add read side of error pipe */ /* * Set options for rediscovery and not-rediscovery modes of * operation. */ shutdownPhaseG = SDP_DONE_STARTING; /* triggered with rediscoverSigCldG */ timeoutShort.tv_sec = 0; /* in quick rediscovery mode */ timeoutShort.tv_usec = SHORT_SELECT_TIMEOUT; timeoutLong.tv_sec = 86400; /* don't thrash on rediscovery */ timeoutLong.tv_usec = 0; for (;;) { COPYBITS(allactivefdsG, readfds); COPYBITS(allactivefdsG, exceptfds); if (rediscoverSigCldG || rediscoverUrgentSigG) { nfound =select(MAXSOCKS, FD_SET_CAST(&readfds), FD_SET_CAST(NULL), FD_SET_CAST(&exceptfds), &timeoutShort); } else { nfound =select(MAXSOCKS, FD_SET_CAST(&readfds), FD_SET_CAST(NULL), FD_SET_CAST(&exceptfds), &timeoutLong); } if (nfound == -1) { /* * Handle select() problem. */ if (errno == EINTR) { /* * A signal happened - let rediscover flags redirect flow * via short select timeouts. */ } else if ((errno == EBADF) || (errno == EFAULT)) { /* * A connection probably dropped. */ if (ttfdG != -1) { if ( GETBIT(exceptfds, ttfdG) ) { /* * Tooltalk connection has gone bad. * * Judgement call - when the Tooltalk connection goes * bad, let dtexec continue rather than doing an exit. */ DetachFromTooltalk(NULL); } } if (errorpipeG[0] != -1) { if ( GETBIT(exceptfds, errorpipeG[0]) ) { /* * Error pipe has gone bad. */ close(errorpipeG[0]); BITCLEAR(allactivefdsG, errorpipeG[0]); errorpipeG[0] = -1; } } } else { /* * We have bad paremeters to select() */ } /* * So that select() errors cannot dominate, now behave as * though only a timeout had occured. */ nfound = 0; } if (nfound > 0) { /* * Have some input to process. Figure out who. */ if (ttfdG != -1) { if ( GETBIT(readfds, ttfdG) ) { /* Clear bit first, since calling input_handler() could */ /* have the side-effect of setting ttfdG to -1! */ BITCLEAR(readfds, ttfdG); /* * Tooltalk activity. * * Note that the input_handler parameters match * an XtInputHandler() style callback in case Xt is * ever used. */ input_handler((char *) NULL, (int *) &junki, (unsigned long *) &junki); } } if (errorpipeG[0] != -1) { if ( GETBIT(readfds, errorpipeG[0]) ) { /* * Stderr activity. * * Read the errorpipe until no more seems available. * Call that good enough and write a time-stamped * block to the errorLog file. */ errorBytes = 0; /* what we have so far */ tmpBuffer = NULL; firstPass = 1; while (1) { char buf; nfound =select(MAXSOCKS, FD_SET_CAST(&readfds), FD_SET_CAST(NULL), FD_SET_CAST(NULL), &timeoutShort); if (nfound > 0) { tmpi = read (errorpipeG[0], &buf, 1); } else { tmpi = 0; } if ( tmpi > 0 ) { /* * Grow buffer to hold entire error stream. */ firstPass = 0; if (tmpBuffer == NULL) tmpBuffer = (char *) malloc( tmpi + 1); else tmpBuffer = (char *) realloc( tmpBuffer, errorBytes + tmpi + 1); /* * Drain error pipe. */ tmpBuffer[errorBytes] = buf; errorBytes += tmpi; tmpBuffer[errorBytes] = '\0'; if (errorBytes < 65535) { /* * Pause a bit and wait for a continuation of * the error stream if there is more. */ select(0, FD_SET_CAST(NULL), FD_SET_CAST(NULL), FD_SET_CAST(NULL), &timeoutShort); } else { /* * We have enough to do a dump now. */ break; } } else { /* * No more to read. */ if (firstPass) { /* * On the first pass after select(), if we have 0 bytes, * it really means the pipe has gone down. */ close(errorpipeG[0]); BITCLEAR(allactivefdsG, errorpipeG[0]); BITCLEAR(readfds, errorpipeG[0]); errorpipeG[0] = -1; } break; } } if (tmpBuffer) { if (!tmpProgName) { tmpProgName = (char *) malloc (strlen (argv[0]) + strlen (cmdLine[0]) + 5); if (!tmpProgName) tmpProgName = argv[0]; else { /* * To identify the process for this stderr, * use both argv[0] and the name of the * process that was execvp'd */ (void) strcpy (tmpProgName, "("); (void) strcat (tmpProgName, argv[0]); (void) strcat (tmpProgName, ") "); (void) strcat (tmpProgName, cmdLine[0]); } } DtMsgLogMessage( tmpProgName, DtMsgLogStderr, "%s", tmpBuffer ); free( tmpBuffer ); } if (errorpipeG[0] != -1) BITCLEAR(readfds, errorpipeG[0]); } } /* * So that select() data cannot dominate, now behave as * though only a timeout had occured. */ nfound = 0; } if (nfound == 0) { /* * Timeout. We are probably rediscovering and have entered * a shutdown phase. The following rediscover handlers are * in priority order. * * Note that by way of timeouts and events, we will make * multiple passes through this block of code. */ if (rediscoverUrgentSigG) { /* * Handle urgent signal. * * Tact: wait awhile and see if a SIGCLD will happen. * If it does, then a normal shutdown will suffice. * If a SIGCLD does not happen, then do a raw exit(0). * Exit is required for BBA anyway. */ if (rediscoverSigCldG) /* * Rather than act on the Urgent Signal, defer to the * SIGCLD Signal shutdown process. */ rediscoverUrgentSigG = 0; else /* * Still in a mode where we have an outstanding * Urgent Signal but no SIGCLD. Bump a counter * which moves us closer to doing an exit(). */ rediscoverUrgentSigG++; /* * After 5 seconds (add select timeout too) waiting for * a SIGCLD, give up and exit. */ if (rediscoverUrgentSigG > ((1000/SHORT_SELECT_TIMEOUT)*5) ) { #if defined(__aix) || defined (__osf__) || defined(CSRG_BASED) || defined(linux) PanicSignal(0); #else PanicSignal(); #endif } } if (rediscoverSigCldG) { /* * Handle SIGCLD signal. * * Under SIGCLD, we will make multiple passes through the * following, implementing a phased shutdown. */ if (shutdownPhaseG == SDP_DONE_STARTING) { /* * Send Done(Request) for starters. */ if (dtSvcProcIdG) DoneRequest(_DtActCHILD_DONE); if (dtSvcProcIdG) { /* * Sit and wait for the Done Reply in select() */ shutdownPhaseG = SDP_DONE_REPLY_WAIT; } else { /* * Unable to send Done Reply. Assume we're on * our own from now on. */ shutdownPhaseG = SDP_DONE_PANIC_CLEANUP; } } if (shutdownPhaseG == SDP_DONE_REPLY_WAIT) { /* * After 5 minutes of passing through REPLY_WAIT, * assume the Done(Reply) will never come in and * move on. */ rediscoverSigCldG++; if (rediscoverSigCldG > ((1000/SHORT_SELECT_TIMEOUT)*300)) { if (dtSvcProcIdG) { /* * Try to detatch from Tooltalk anyway. */ DetachFromTooltalk(NULL); } shutdownPhaseG = SDP_DONE_PANIC_CLEANUP; } /* * See if the Tooltalk connection is still alive. If * not, then no reason to wait around. */ else if (!dtSvcProcIdG) { shutdownPhaseG = SDP_DONE_PANIC_CLEANUP; } } if (shutdownPhaseG == SDP_DONE_REPLIED) { /* * We have our Done(Reply), so proceed. */ if (dtSvcProcIdG) shutdownPhaseG = SDP_FINAL_LINGER; else shutdownPhaseG = SDP_DONE_PANIC_CLEANUP; } if (shutdownPhaseG == SDP_DONE_PANIC_CLEANUP) { /* * We cannot talk with caller, so do cleanup * of tmp files. */ for (i = 0; i < tmpFileCntG; i++ ) { chmod( tmpFilesG[i], (S_IRUSR|S_IWUSR) ); unlink( tmpFilesG[i] ); } shutdownPhaseG = SDP_FINAL_LINGER; } if (shutdownPhaseG == SDP_FINAL_LINGER) { /* * All done. */ static int skipFirst = 1; if (skipFirst) { /* * Rather than a quick departure from the select() * loop, make one more pass. If the child has gone * down quickly, the SIGCLD may have caused us to * get here before any errorPipeG information has * had a chance to reach us. */ skipFirst = 0; } else { FinalLinger(); } } } } } }
int ntpdmain( int argc, char *argv[] ) { l_fp now; struct recvbuf *rbuf; const char * logfilename; # ifdef HAVE_UMASK mode_t uv; # endif # if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ uid_t uid; # endif # if defined(HAVE_WORKING_FORK) long wait_sync = 0; int pipe_fds[2]; int rc; int exit_code; # ifdef _AIX struct sigaction sa; # endif # if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY) int fid; # endif # endif /* HAVE_WORKING_FORK*/ # ifdef SCO5_CLOCK int fd; int zero; # endif # ifdef HAVE_UMASK uv = umask(0); if (uv) umask(uv); else umask(022); # endif saved_argc = argc; saved_argv = argv; progname = argv[0]; initializing = TRUE; /* mark that we are initializing */ parse_cmdline_opts(&argc, &argv); # ifdef DEBUG debug = OPT_VALUE_SET_DEBUG_LEVEL; # endif if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT) # ifdef DEBUG || debug # endif || HAVE_OPT(SAVECONFIGQUIT)) nofork = TRUE; init_logging(progname, NLOG_SYNCMASK, TRUE); /* honor -l/--logfile option to log to a file */ if (HAVE_OPT(LOGFILE)) { logfilename = OPT_ARG(LOGFILE); syslogit = FALSE; change_logfile(logfilename, FALSE); } else { logfilename = NULL; if (nofork) msyslog_term = TRUE; if (HAVE_OPT(SAVECONFIGQUIT)) syslogit = FALSE; } msyslog(LOG_NOTICE, "%s: Starting\n", Version); { int i; char buf[1024]; /* Secret knowledge of msyslog buf length */ char *cp = buf; /* Note that every arg has an initial space character */ snprintf(cp, sizeof(buf), "Command line:"); cp += strlen(cp); for (i = 0; i < saved_argc ; ++i) { snprintf(cp, sizeof(buf) - (cp - buf), " %s", saved_argv[i]); cp += strlen(cp); } msyslog(LOG_NOTICE, "%s", buf); } /* * Install trap handlers to log errors and assertion failures. * Default handlers print to stderr which doesn't work if detached. */ isc_assertion_setcallback(assertion_failed); isc_error_setfatal(library_fatal_error); isc_error_setunexpected(library_unexpected_error); /* MPE lacks the concept of root */ # if defined(HAVE_GETUID) && !defined(MPE) uid = getuid(); if (uid && !HAVE_OPT( SAVECONFIGQUIT )) { msyslog_term = TRUE; msyslog(LOG_ERR, "must be run as root, not uid %ld", (long)uid); exit(1); } # endif /* * Enable the Multi-Media Timer for Windows? */ # ifdef SYS_WINNT if (HAVE_OPT( MODIFYMMTIMER )) set_mm_timer(MM_TIMER_HIRES); # endif #ifdef HAVE_DNSREGISTRATION /* * Enable mDNS registrations? */ if (HAVE_OPT( MDNS )) { mdnsreg = TRUE; } #endif /* HAVE_DNSREGISTRATION */ if (HAVE_OPT( NOVIRTUALIPS )) listen_to_virtual_ips = 0; /* * --interface, listen on specified interfaces */ if (HAVE_OPT( INTERFACE )) { int ifacect = STACKCT_OPT( INTERFACE ); const char** ifaces = STACKLST_OPT( INTERFACE ); sockaddr_u addr; while (ifacect-- > 0) { add_nic_rule( is_ip_address(*ifaces, AF_UNSPEC, &addr) ? MATCH_IFADDR : MATCH_IFNAME, *ifaces, -1, ACTION_LISTEN); ifaces++; } } if (HAVE_OPT( NICE )) priority_done = 0; # ifdef HAVE_SCHED_SETSCHEDULER if (HAVE_OPT( PRIORITY )) { config_priority = OPT_VALUE_PRIORITY; config_priority_override = 1; priority_done = 0; } # endif # ifdef HAVE_WORKING_FORK do { /* 'loop' once */ if (!HAVE_OPT( WAIT_SYNC )) break; wait_sync = OPT_VALUE_WAIT_SYNC; if (wait_sync <= 0) { wait_sync = 0; break; } /* -w requires a fork() even with debug > 0 */ nofork = FALSE; if (pipe(pipe_fds)) { exit_code = (errno) ? errno : -1; msyslog(LOG_ERR, "Pipe creation failed for --wait-sync: %m"); exit(exit_code); } waitsync_fd_to_close = pipe_fds[1]; } while (0); /* 'loop' once */ # endif /* HAVE_WORKING_FORK */ init_lib(); # ifdef SYS_WINNT /* * Start interpolation thread, must occur before first * get_systime() */ init_winnt_time(); # endif /* * Initialize random generator and public key pair */ get_systime(&now); ntp_srandom((int)(now.l_i * now.l_uf)); /* * Detach us from the terminal. May need an #ifndef GIZMO. */ if (!nofork) { # ifdef HAVE_WORKING_FORK rc = fork(); if (-1 == rc) { exit_code = (errno) ? errno : -1; msyslog(LOG_ERR, "fork: %m"); exit(exit_code); } if (rc > 0) { /* parent */ exit_code = wait_child_sync_if(pipe_fds[0], wait_sync); exit(exit_code); } /* * child/daemon * close all open files excepting waitsync_fd_to_close. * msyslog() unreliable until after init_logging(). */ closelog(); if (syslog_file != NULL) { fclose(syslog_file); syslog_file = NULL; syslogit = TRUE; } close_all_except(waitsync_fd_to_close); INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \ && 2 == dup2(0, 2)); init_logging(progname, 0, TRUE); /* we lost our logfile (if any) daemonizing */ setup_logfile(logfilename); # ifdef SYS_DOMAINOS { uid_$t puid; status_$t st; proc2_$who_am_i(&puid); proc2_$make_server(&puid, &st); } # endif /* SYS_DOMAINOS */ # ifdef HAVE_SETSID if (setsid() == (pid_t)-1) msyslog(LOG_ERR, "setsid(): %m"); # elif defined(HAVE_SETPGID) if (setpgid(0, 0) == -1) msyslog(LOG_ERR, "setpgid(): %m"); # else /* !HAVE_SETSID && !HAVE_SETPGID follows */ # ifdef TIOCNOTTY fid = open("/dev/tty", 2); if (fid >= 0) { ioctl(fid, (u_long)TIOCNOTTY, NULL); close(fid); } # endif /* TIOCNOTTY */ ntp_setpgrp(0, getpid()); # endif /* !HAVE_SETSID && !HAVE_SETPGID */ # ifdef _AIX /* Don't get killed by low-on-memory signal. */ sa.sa_handler = catch_danger; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGDANGER, &sa, NULL); # endif /* _AIX */ # endif /* HAVE_WORKING_FORK */ } # ifdef SCO5_CLOCK /* * SCO OpenServer's system clock offers much more precise timekeeping * on the base CPU than the other CPUs (for multiprocessor systems), * so we must lock to the base CPU. */ fd = open("/dev/at1", O_RDONLY); if (fd >= 0) { zero = 0; if (ioctl(fd, ACPU_LOCK, &zero) < 0) msyslog(LOG_ERR, "cannot lock to base CPU: %m"); close(fd); } # endif # if defined(HAVE_MLOCKALL) # ifdef HAVE_SETRLIMIT ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k"); # ifdef RLIMIT_MEMLOCK /* * The default RLIMIT_MEMLOCK is very low on Linux systems. * Unless we increase this limit malloc calls are likely to * fail if we drop root privilege. To be useful the value * has to be larger than the largest ntpd resident set size. */ ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB"); # endif /* RLIMIT_MEMLOCK */ # endif /* HAVE_SETRLIMIT */ /* * lock the process into memory */ if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != mlockall(MCL_CURRENT|MCL_FUTURE)) msyslog(LOG_ERR, "mlockall(): %m"); # else /* !HAVE_MLOCKALL follows */ # ifdef HAVE_PLOCK # ifdef PROCLOCK # ifdef _AIX /* * set the stack limit for AIX for plock(). * see get_aix_stack() for more info. */ if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0) msyslog(LOG_ERR, "Cannot adjust stack limit for plock: %m"); # endif /* _AIX */ /* * lock the process into memory */ if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK)) msyslog(LOG_ERR, "plock(PROCLOCK): %m"); # else /* !PROCLOCK follows */ # ifdef TXTLOCK /* * Lock text into ram */ if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK)) msyslog(LOG_ERR, "plock(TXTLOCK) error: %m"); # else /* !TXTLOCK follows */ msyslog(LOG_ERR, "plock() - don't know what to lock!"); # endif /* !TXTLOCK */ # endif /* !PROCLOCK */ # endif /* HAVE_PLOCK */ # endif /* !HAVE_MLOCKALL */ /* * Set up signals we pay attention to locally. */ # ifdef SIGDIE1 signal_no_reset(SIGDIE1, finish); signal_no_reset(SIGDIE2, finish); signal_no_reset(SIGDIE3, finish); signal_no_reset(SIGDIE4, finish); # endif # ifdef SIGBUS signal_no_reset(SIGBUS, finish); # endif # if !defined(SYS_WINNT) && !defined(VMS) # ifdef DEBUG (void) signal_no_reset(MOREDEBUGSIG, moredebug); (void) signal_no_reset(LESSDEBUGSIG, lessdebug); # else (void) signal_no_reset(MOREDEBUGSIG, no_debug); (void) signal_no_reset(LESSDEBUGSIG, no_debug); # endif /* DEBUG */ # endif /* !SYS_WINNT && !VMS */ /* * Set up signals we should never pay attention to. */ # ifdef SIGPIPE signal_no_reset(SIGPIPE, SIG_IGN); # endif /* * Call the init_ routines to initialize the data structures. * * Exactly what command-line options are we expecting here? */ INIT_SSL(); init_auth(); init_util(); init_restrict(); init_mon(); init_timer(); init_request(); init_control(); init_peer(); # ifdef REFCLOCK init_refclock(); # endif set_process_priority(); init_proto(); /* Call at high priority */ init_io(); init_loopfilter(); mon_start(MON_ON); /* monitor on by default now */ /* turn off in config if unwanted */ /* * Get the configuration. This is done in a separate module * since this will definitely be different for the gizmo board. */ getconfig(argc, argv); loop_config(LOOP_DRIFTINIT, 0); report_event(EVNT_SYSRESTART, NULL, NULL); initializing = FALSE; # ifdef HAVE_DROPROOT if (droproot) { /* Drop super-user privileges and chroot now if the OS supports this */ # ifdef HAVE_LINUX_CAPABILITIES /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */ if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) { msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" ); exit(-1); } # else /* we need a user to switch to */ if (user == NULL) { msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" ); exit(-1); } # endif /* HAVE_LINUX_CAPABILITIES */ if (user != NULL) { if (isdigit((unsigned char)*user)) { sw_uid = (uid_t)strtoul(user, &endp, 0); if (*endp != '\0') goto getuser; if ((pw = getpwuid(sw_uid)) != NULL) { free(user); user = estrdup(pw->pw_name); sw_gid = pw->pw_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find user ID %s", user); exit (-1); } } else { getuser: errno = 0; if ((pw = getpwnam(user)) != NULL) { sw_uid = pw->pw_uid; sw_gid = pw->pw_gid; } else { if (errno) msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user); else msyslog(LOG_ERR, "Cannot find user `%s'", user); exit (-1); } } } if (group != NULL) { if (isdigit((unsigned char)*group)) { sw_gid = (gid_t)strtoul(group, &endp, 0); if (*endp != '\0') goto getgroup; } else { getgroup: if ((gr = getgrnam(group)) != NULL) { sw_gid = gr->gr_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find group `%s'", group); exit (-1); } } } if (chrootdir ) { /* make sure cwd is inside the jail: */ if (chdir(chrootdir)) { msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir); exit (-1); } if (chroot(chrootdir)) { msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir); exit (-1); } if (chdir("/")) { msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m"); exit (-1); } } if (user && initgroups(user, sw_gid)) { msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user); exit (-1); } if (group && setgid(sw_gid)) { msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group); exit (-1); } if (group && setegid(sw_gid)) { msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group); exit (-1); } if (user && setuid(sw_uid)) { msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user); exit (-1); } if (user && seteuid(sw_uid)) { msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user); exit (-1); } # ifndef HAVE_LINUX_CAPABILITIES /* * for now assume that the privilege to bind to privileged ports * is associated with running with uid 0 - should be refined on * ports that allow binding to NTP_PORT with uid != 0 */ disable_dynamic_updates |= (sw_uid != 0); /* also notifies routing message listener */ # endif if (disable_dynamic_updates && interface_interval) { interface_interval = 0; msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking"); } # ifdef HAVE_LINUX_CAPABILITIES { /* * We may be running under non-root uid now, but we still hold full root privileges! * We drop all of them, except for the crucial one or two: cap_sys_time and * cap_net_bind_service if doing dynamic interface tracking. */ cap_t caps; char *captext; captext = (0 != interface_interval) ? "cap_sys_time,cap_net_bind_service=pe" : "cap_sys_time=pe"; caps = cap_from_text(captext); if (!caps) { msyslog(LOG_ERR, "cap_from_text(%s) failed: %m", captext); exit(-1); } if (-1 == cap_set_proc(caps)) { msyslog(LOG_ERR, "cap_set_proc() failed to drop root privs: %m"); exit(-1); } cap_free(caps); } # endif /* HAVE_LINUX_CAPABILITIES */ root_dropped = TRUE; fork_deferred_worker(); } /* if (droproot) */ # endif /* HAVE_DROPROOT */ /* * Use select() on all on all input fd's for unlimited * time. select() will terminate on SIGALARM or on the * reception of input. Using select() means we can't do * robust signal handling and we get a potential race * between checking for alarms and doing the select(). * Mostly harmless, I think. */ /* * On VMS, I suspect that select() can't be interrupted * by a "signal" either, so I take the easy way out and * have select() time out after one second. * System clock updates really aren't time-critical, * and - lacking a hardware reference clock - I have * yet to learn about anything else that is. */ # ifdef HAVE_IO_COMPLETION_PORT for (;;) { GetReceivedBuffers(); # else /* normal I/O */ BLOCK_IO_AND_ALARM(); was_alarmed = FALSE; for (;;) { # ifndef HAVE_SIGNALED_IO fd_set rdfdes; int nfound; # endif if (alarm_flag) { /* alarmed? */ was_alarmed = TRUE; alarm_flag = FALSE; } if (!was_alarmed && !has_full_recv_buffer()) { /* * Nothing to do. Wait for something. */ # ifndef HAVE_SIGNALED_IO rdfdes = activefds; # if !defined(VMS) && !defined(SYS_VXWORKS) nfound = select(maxactivefd + 1, &rdfdes, NULL, NULL, NULL); # else /* VMS, VxWorks */ /* make select() wake up after one second */ { struct timeval t1; t1.tv_sec = 1; t1.tv_usec = 0; nfound = select(maxactivefd + 1, &rdfdes, NULL, NULL, &t1); } # endif /* VMS, VxWorks */ if (nfound > 0) { l_fp ts; get_systime(&ts); input_handler(&ts); } else if (nfound == -1 && errno != EINTR) { msyslog(LOG_ERR, "select() error: %m"); } # ifdef DEBUG else if (debug > 4) { msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound); } else { DPRINTF(1, ("select() returned %d: %m\n", nfound)); } # endif /* DEBUG */ # else /* HAVE_SIGNALED_IO */ wait_for_signal(); # endif /* HAVE_SIGNALED_IO */ if (alarm_flag) { /* alarmed? */ was_alarmed = TRUE; alarm_flag = FALSE; } } if (was_alarmed) { UNBLOCK_IO_AND_ALARM(); /* * Out here, signals are unblocked. Call timer routine * to process expiry. */ timer(); was_alarmed = FALSE; BLOCK_IO_AND_ALARM(); } # endif /* !HAVE_IO_COMPLETION_PORT */ # ifdef DEBUG_TIMING { l_fp pts; l_fp tsa, tsb; int bufcount = 0; get_systime(&pts); tsa = pts; # endif rbuf = get_full_recv_buffer(); while (rbuf != NULL) { if (alarm_flag) { was_alarmed = TRUE; alarm_flag = FALSE; } UNBLOCK_IO_AND_ALARM(); if (was_alarmed) { /* avoid timer starvation during lengthy I/O handling */ timer(); was_alarmed = FALSE; } /* * Call the data procedure to handle each received * packet. */ if (rbuf->receiver != NULL) { # ifdef DEBUG_TIMING l_fp dts = pts; L_SUB(&dts, &rbuf->recv_time); DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9))); collect_timing(rbuf, "buffer processing delay", 1, &dts); bufcount++; # endif (*rbuf->receiver)(rbuf); } else { msyslog(LOG_ERR, "fatal: receive buffer callback NULL"); abort(); } BLOCK_IO_AND_ALARM(); freerecvbuf(rbuf); rbuf = get_full_recv_buffer(); } # ifdef DEBUG_TIMING get_systime(&tsb); L_SUB(&tsb, &tsa); if (bufcount) { collect_timing(NULL, "processing", bufcount, &tsb); DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9))); } } # endif /* * Go around again */ # ifdef HAVE_DNSREGISTRATION if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) { mdnsreg = current_time; msyslog(LOG_INFO, "Attempting to register mDNS"); if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) { if (!--mdnstries) { msyslog(LOG_ERR, "Unable to register mDNS, giving up."); } else { msyslog(LOG_INFO, "Unable to register mDNS, will try later."); } } else { msyslog(LOG_INFO, "mDNS service registered."); mdnsreg = FALSE; } } # endif /* HAVE_DNSREGISTRATION */ } UNBLOCK_IO_AND_ALARM(); return 1; } #endif /* !SIM */ #if !defined(SIM) && defined(SIGDIE1) /* * finish - exit gracefully */ static RETSIGTYPE finish( int sig ) { const char *sig_desc; sig_desc = NULL; #ifdef HAVE_STRSIGNAL sig_desc = strsignal(sig); #endif if (sig_desc == NULL) sig_desc = ""; msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname, sig, sig_desc); # ifdef HAVE_DNSREGISTRATION if (mdns != NULL) DNSServiceRefDeallocate(mdns); # endif exit(0); } #endif /* !SIM && SIGDIE1 */ #ifndef SIM /* * wait_child_sync_if - implements parent side of -w/--wait-sync */ # ifdef HAVE_WORKING_FORK static int wait_child_sync_if( int pipe_read_fd, long wait_sync ) { int rc; int exit_code; time_t wait_end_time; time_t cur_time; time_t wait_rem; fd_set readset; struct timeval wtimeout; if (0 == wait_sync) return 0; /* waitsync_fd_to_close used solely by child */ close(waitsync_fd_to_close); wait_end_time = time(NULL) + wait_sync; do { cur_time = time(NULL); wait_rem = (wait_end_time > cur_time) ? (wait_end_time - cur_time) : 0; wtimeout.tv_sec = wait_rem; wtimeout.tv_usec = 0; FD_ZERO(&readset); FD_SET(pipe_read_fd, &readset); rc = select(pipe_read_fd + 1, &readset, NULL, NULL, &wtimeout); if (-1 == rc) { if (EINTR == errno) continue; exit_code = (errno) ? errno : -1; msyslog(LOG_ERR, "--wait-sync select failed: %m"); return exit_code; } if (0 == rc) { /* * select() indicated a timeout, but in case * its timeouts are affected by a step of the * system clock, select() again with a zero * timeout to confirm. */ FD_ZERO(&readset); FD_SET(pipe_read_fd, &readset); wtimeout.tv_sec = 0; wtimeout.tv_usec = 0; rc = select(pipe_read_fd + 1, &readset, NULL, NULL, &wtimeout); if (0 == rc) /* select() timeout */ break; else /* readable */ return 0; } else /* readable */ return 0; } while (wait_rem > 0); fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n", progname, wait_sync); return ETIMEDOUT; }
int input_poll(void) { int ret, i, readed; if (fds_index == 0) return 0; ret = poll(fds, fds_index, 1000); for(i=0;i<fds_index;i++) { if (fds[i].revents & POLLRDNORM) { readed = read(fds[i].fd, &input_event_data, sizeof(struct input_event)); if(readed > 0) { #ifdef ANDROID printf("Type: %d, code: %d, value: %d\n", input_event_data.type, input_event_data.code, input_event_data.value); #endif if (input_event_data.type == EV_SYN) { // raise event // if (events[i].type & EVENT_KEY > 0) // { // printf("KEY: %d\n", events[i].key); // } // // if (events[i].type & EVENT_ABS > 0) // { // printf("ABS: X: %d, Y: %d, Z: %d\n", events[i].abs_x, events[i].abs_y, events[i].abs_z); // } // // if (events[i].type & EVENT_REL > 0) // { // printf("REL: X: %d, Y: %d, Z: %d\n", events[i].x, events[i].y, events[i].z); // } if (input_handler != NULL) { input_handler(&events[i]); } events[i].type = 0; } else if (input_event_data.type == EV_KEY) { // type == EV_KEY, Code = BTN/KEY, Value = 1/0 //printf("Type: %d, code: %d, value: %d\n", input_event_data.type, input_event_data.code, input_event_data.value); events[i].type |= EVENT_KEY; events[i].key = input_event_data.code; events[i].key_value = input_event_data.value; } else if (input_event_data.type == EV_ABS) { if (input_event_data.code == ABS_X || input_event_data.code == ABS_MT_POSITION_X) { events[i].abs_x = input_event_data.value; } else if (input_event_data.code == ABS_Y || input_event_data.code == ABS_MT_POSITION_Y) { events[i].abs_y = input_event_data.value; } else if (input_event_data.code == ABS_Z || input_event_data.code == ABS_WHEEL) { events[i].abs_z = input_event_data.value; } events[i].type |= EVENT_ABS; } else if (input_event_data.type == EV_REL) { if (input_event_data.code == REL_X) { events[i].x = input_event_data.value; } else if (input_event_data.code == REL_Y) { events[i].y = input_event_data.value; } else if (input_event_data.code == REL_Z || input_event_data.code == REL_WHEEL) { events[i].z = input_event_data.value; } events[i].type |= EVENT_REL; } } } } return ret; }