Example #1
0
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;
}
Example #2
0
const char *get_wanip(void)
{
	if (!check_wanup()) return "0.0.0.0";

	return (*get_wanfaces()).iface[0].ip;
}