int API main () { struct routeup rtc; if (routeup_setup (&rtc)) return 1; while (!routeup_once (&rtc, 0)) printf ("n\n"); routeup_teardown (&rtc); return 0; }
struct event *event_routeup() { struct routeup *rtup = malloc(sizeof *rtup); struct event *e; if (!rtup) return NULL; if (!routeup_setup(rtup)) { perror ("event_routeup routeup_setup() failed"); free(rtup); return NULL; } e = _event_subproc(_routeup, (void*)rtup); /* free it in the parent only */ routeup_teardown(rtup); if (e) e->name = "routeup"; return e; }
int API main (int argc, char *argv[], char *envp[]) { struct routeup rtc; int hwclock_fd = -1; time_t last_success = 0; struct opts opts; int wait_time = 0; set_conf_defaults(&opts); parse_argv(&opts, argc, argv); check_conf(&opts); load_conf(&opts); check_conf(&opts); if (!opts.sources) add_source_to_conf(&opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY); /* grab a handle to /dev/rtc for sync_hwclock() */ if (opts.should_sync_hwclock && (hwclock_fd = open (DEFAULT_RTC_DEVICE, O_RDONLY)) < 0) { pinfo ("can't open hwclock fd"); opts.should_sync_hwclock = 0; } /* set up a netlink context if we need one */ if (opts.should_netlink && routeup_setup (&rtc)) pfatal ("Can't open netlink socket"); if (!is_sane_time (time (NULL))) { struct timeval tv = { 0, 0 }; /* * If the time is before the build timestamp, we're probably on * a system with a broken rtc. Try loading the timestamp off * disk. */ tv.tv_sec = RECENT_COMPILE_DATE; if (opts.should_load_disk && load_disk_timestamp (timestamp_path, &tv.tv_sec)) pinfo ("can't load disk timestamp"); if (!opts.dry_run && settimeofday (&tv, NULL)) pfatal ("settimeofday() failed"); dbus_announce(); /* * don't save here - we either just loaded this time or used the * default time, and neither of those are good to save */ sync_and_save (hwclock_fd, opts.should_sync_hwclock, 0); } /* register a signal handler to save time at shutdown */ if (opts.should_save_disk) signal (SIGTERM, sigterm_handler); /* * Try once right away. If we fail, wait for a route to appear, then try * for a while; repeat whenever another route appears. Try until we * succeed. */ if (!tlsdate (&opts, envp)) { last_success = time (NULL); sync_and_save (hwclock_fd, opts.should_sync_hwclock, opts.should_save_disk); dbus_announce(); } /* * Loop until we catch a fatal signal or routeup_once() fails. We run * tlsdate at least once a day, but possibly as often as routes come up; * this should handle cases like a VPN being brought up and down * periodically. */ wait_time = add_jitter(opts.steady_state_interval, opts.jitter); while (wait_for_event (&rtc, opts.should_netlink, wait_time) >= 0) { /* * If a route just came up, run tlsdate; if it * succeeded, then we're good and can keep time locally * from now on. */ int i; int backoff = opts.wait_between_tries; wait_time = add_jitter(opts.steady_state_interval, opts.jitter); if (time (NULL) - last_success < opts.min_steady_state_interval) continue; for (i = 0; i < opts.max_tries && tlsdate (&opts, envp); ++i) { if (backoff < 1) fatal ("backoff too small? %d", backoff); sleep (backoff); if (backoff < MAX_SANE_BACKOFF) backoff *= 2; } if (i != opts.max_tries) { last_success = time (NULL); info ("tlsdate succeeded"); sync_and_save (hwclock_fd, opts.should_sync_hwclock, opts.should_save_disk); dbus_announce(); } } return 1; }