static int ntpsync_main(int argc, char **argv) { char *servers, *t, *p; char *addr[10]; char *ips; char *nvkiss; int count; int i; struct hostent *he; struct in_addr ia; int retries; int nu; char s[512]; time_t tt; struct tm *tms; enum { USER, INIT, CRON } mode; nu = nvram_get_int("ntp_updates"); mode = USER; if (argc == 2) { if (strcmp(argv[1], "--cron") == 0) { // try for a few minutes if (nu <= 0) { eval("cru", "d", "ntpsync"); return 0; } mode = CRON; } else if (strcmp(argv[1], "--init") == 0) { // try forever, schedule cron job if (fork() != 0) return 0; mode = INIT; } else { return 1; } } else if (argc != 1) { return 1; } _dprintf("[ntpsync %ld] start\n", get_uptime()); if ((get_wan_proto() != WP_DISABLED) && (mode != INIT) && (!check_wanup()) && (nvram_match("ntp_tdod", "0"))) { _dprintf("WAN is down, not updating."); return 1; } srand(time(0)); retries = 0; while (1) { _dprintf("[ntpsync %ld] while\n", get_uptime()); count = 0; servers = p = strdup(nvram_safe_get("ntp_server")); if (!servers) { printf("Not enough memory\n"); return 1; } while ((count < 10) && ((t = strsep(&p, " ")) != NULL)) { if (*t != 0) addr[count++] = t; } if (count == 0) addr[count++] = "pool.ntp.org"; while (count > 0) { i = (rand() % count); _dprintf("[ntpsync] i=%d addr=%s\n", i, addr[i]); if ((he = gethostbyname(addr[i])) != NULL) { memcpy(&ia, he->h_addr_list[0], sizeof(ia)); ips = inet_ntoa(ia); _dprintf("ip = %s\n", ips); nvkiss = nvram_safe_get("ntp_kiss"); if (find_word(nvkiss, ips)) { _dprintf("kiss: %s\n", ips); } else { switch (ntpc(ia)) { case 0: _dprintf("[ntpsync] %ld OK\n", get_uptime()); if (mode == INIT) { tt = time(0); if ((nu > 0) && ((tms = localtime(&tt)) != NULL)) { // add some randomness to make the servers happier / avoid the xx:00 rush sprintf(s, "%d ", (tms->tm_min + 20 + (rand() % 20)) % 60); // schedule every nu hours for (i = 0; i < 24; ++i) { if ((i % nu) == 0) sprintf(s + strlen(s), "%s%d", i ? "," : "", (i + tms->tm_hour + 1) % 24); } strcat(s, " * * * ntpsync --cron"); eval("cru", "a", "ntpsync", s); } } // make sure access restriction is ok eval("rcheck"); _dprintf("[ntpsync] %ld exit\n", get_uptime()); return 0; case 2: while ((nvkiss) && (strlen(nvkiss) > 128)) nvkiss = strchr(nvkiss + 1, ' '); if (nvkiss) strlcpy(s, nvkiss, sizeof(s)); else s[0] = 0; add_word(s, ips, sizeof(s)); nvram_set("ntp_kiss", s); syslog(LOG_WARNING, "Received a kiss of death packet from %s (%s).", addr[i], ips); break; } } } addr[i] = addr[--count]; } free(servers); if (mode == USER) break; if ((mode == CRON) && (retries == 5)) break; if (++retries > 300) retries = 300; // 5m _dprintf("[ntpsync %ld] sleep=%d\n", get_uptime(), retries); sleep(retries); } _dprintf("[ntpsync] %ld exit\n", get_uptime()); return 1; }
const char *get_wanip(void) { if (!check_wanup()) return "0.0.0.0"; return (*get_wanfaces()).iface[0].ip; }