X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftimeserver.c;h=038d44b3514ac0604bf2f814d36b7e4248e5b6b7;hb=5ed7094e4994d03c7606f25881918565c81d1c24;hp=9202df89d02f94fbdbca8de6c75555d795ca6c00;hpb=bbd19813c457227a2861c05e9ebc676f8feb7f10;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/timeserver.c b/src/timeserver.c index 9202df8..038d44b 100644 --- a/src/timeserver.c +++ b/src/timeserver.c @@ -26,302 +26,141 @@ #include #include -#include -#include -#include #include "connman.h" -static GSList *ts_list = NULL; +static GSList *driver_list = NULL; +static GHashTable *server_hash = NULL; -static GResolv *resolv = NULL; -static int resolv_id = 0; - -static void resolv_debug(const char *str, void *data) -{ - connman_info("%s: %s\n", (const char *) data, str); -} -static void save_timeservers(char **servers) +static gint compare_priority(gconstpointer a, gconstpointer b) { - GKeyFile *keyfile; - int cnt; - - keyfile = __connman_storage_load_global(); - if (keyfile == NULL) - keyfile = g_key_file_new(); - - for (cnt = 0; servers != NULL && servers[cnt] != NULL; cnt++); + const struct connman_timeserver_driver *driver1 = a; + const struct connman_timeserver_driver *driver2 = b; - g_key_file_set_string_list(keyfile, "global", "Timeservers", - (const gchar **)servers, cnt); - - __connman_storage_save_global(keyfile); - - g_key_file_free(keyfile); - - return; + return driver2->priority - driver1->priority; } -static char **load_timeservers() +/** + * connman_timeserver_driver_register: + * @driver: timeserver driver definition + * + * Register a new timeserver driver + * + * Returns: %0 on success + */ +int connman_timeserver_driver_register(struct connman_timeserver_driver *driver) { - GKeyFile *keyfile; - GError *error = NULL; - char **servers = NULL; - - keyfile = __connman_storage_load_global(); - if (keyfile == NULL) - return NULL; - - servers = g_key_file_get_string_list(keyfile, "global", - "Timeservers", NULL, &error); - if (error) { - DBG("Error loading timeservers: %s", error->message); - g_error_free(error); - } + DBG("driver %p name %s", driver, driver->name); - g_key_file_free(keyfile); + driver_list = g_slist_insert_sorted(driver_list, driver, + compare_priority); - return servers; + return 0; } -static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data) +/** + * connman_timeserver_driver_unregister: + * @driver: timeserver driver definition + * + * Remove a previously registered timeserver driver + */ +void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driver) { - int i; + DBG("driver %p name %s", driver, driver->name); - DBG("status %d", status); - - if (status == G_RESOLV_RESULT_STATUS_SUCCESS) { - if (results != NULL) { - for (i = 0; results[i]; i++) - DBG("result: %s", results[i]); - - __connman_ntp_start(results[0]); - - return; - } - } - - /* If resolving fails, move to the next server */ - __connman_timeserver_sync_next(); + driver_list = g_slist_remove(driver_list, driver); } -/* - * Once the timeserver list (ts_list) is created, we start querying the - * servers one by one. If resolving fails on one of them, we move to the - * next one. The user can enter either an IP address or a URL for the - * timeserver. We only resolve the urls. Once we have a IP for the NTP - * server, we start querying it for time corrections. +/** + * connman_timeserver_append: + * @server: server address + * + * Append time server server address to current list */ -void __connman_timeserver_sync_next() +int connman_timeserver_append(const char *server) { - char *server; - int ret; - struct addrinfo hints; - struct addrinfo *addr; - - __connman_ntp_stop(); - - /* Get the 1st server in the list */ - if (ts_list == NULL) - return; - - server = ts_list->data; - - ts_list = g_slist_delete_link(ts_list, ts_list); - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - addr = NULL; - - ret = getaddrinfo(server, NULL, &hints, &addr); - freeaddrinfo(addr); - - /* if its a IP , directly query it. */ - if (ret == 0) { - DBG("Using timeservers %s", server); + GSList *list; - __connman_ntp_start(server); + DBG("server %s", server); - g_free(server); - return; - } - - DBG("Resolving server %s", server); - - resolv_id = g_resolv_lookup_hostname(resolv, server, - resolv_result, NULL); - - g_free(server); - - return; -} - - -/* - * __connman_timeserver_sync function recreates the timeserver - * list which will be used to determine NTP server for time corrections. - * It must be called everytime the default service changes, the service - * timeserver(s) or gatway changes or the global timeserver(s) changes. - * The service settings take priority over the global timeservers. - */ -int __connman_timeserver_sync(struct connman_service *default_service) -{ - struct connman_service *service; - struct connman_network *network; - char **timeservers; - char **service_ts; - const char *service_gw; - int index, i; - - if (default_service != NULL) - service = default_service; - else - service = __connman_service_get_default(); - - if (service == NULL) + if (server == NULL) return -EINVAL; - if (resolv == NULL) + /* This server is already handled by a driver */ + if (g_hash_table_lookup(server_hash, server)) return 0; - /* - * Before be start creating the new timeserver list we must stop - * any ongoing ntp query and server resolution. - */ - - __connman_ntp_stop(); - - if (resolv_id > 0) - g_resolv_cancel_lookup(resolv, resolv_id); - - if (ts_list != NULL) { - g_slist_free_full(ts_list, g_free); - ts_list = NULL; - } - - service_ts = connman_service_get_timeservers(service); - - /* First add Service Timeservers via DHCP to the list */ - for (i=0; service_ts != NULL && service_ts[i] != NULL; i++) - ts_list = g_slist_prepend(ts_list, g_strdup(service_ts[i])); - - network = __connman_service_get_network(service); - - index = connman_network_get_index(network); - service_gw = __connman_ipconfig_get_gateway_from_index(index); + for (list = driver_list; list; list = list->next) { + struct connman_timeserver_driver *driver = list->data; + char *new_server; - /* Then add Service Gateway to the list */ - if (service_gw != NULL) - ts_list = g_slist_prepend(ts_list, g_strdup(service_gw)); + if (driver->append == NULL) + continue; - /* Then add Global Timeservers to the list */ - timeservers = load_timeservers(); + new_server = g_strdup(server); + if (new_server == NULL) + return -ENOMEM; - for (i=0; timeservers != NULL && timeservers[i] != NULL; i++) - ts_list = g_slist_prepend(ts_list, g_strdup(timeservers[i])); - - if (ts_list == NULL) { - DBG("No timeservers set."); - return 0; + if (driver->append(server) == 0) { + g_hash_table_insert(server_hash, new_server, driver); + return 0; + } else { + g_free(new_server); + } } - ts_list = g_slist_reverse(ts_list); - - __connman_timeserver_sync_next(); - - return 0; + return -ENOENT; } -static int timeserver_start(struct connman_service *service) +/** + * connman_timeserver_remove: + * @server: server address + * + * Remover time server server address from current list + */ +int connman_timeserver_remove(const char *server) { - char **nameservers; - int i; + struct connman_timeserver_driver *driver; - DBG("service %p", service); + DBG("server %s", server); - i = __connman_service_get_index(service); - if (i < 0) + if (server == NULL) return -EINVAL; - nameservers = connman_service_get_nameservers(service); - if (nameservers == NULL) + driver = g_hash_table_lookup(server_hash, server); + if (driver == NULL) return -EINVAL; - /* Stop an already ongoing resolution, if there is one */ - if (resolv_id > 0) - g_resolv_cancel_lookup(resolv, resolv_id); - - /* get rid of the old resolver */ - if (resolv != NULL) { - g_resolv_unref(resolv); - resolv = NULL; - } + g_hash_table_remove(server_hash, server); - resolv = g_resolv_new(i); - if (resolv == NULL) - return -ENOMEM; + if (driver->remove == NULL) + return -ENOENT; - if (getenv("CONNMAN_RESOLV_DEBUG")) - g_resolv_set_debug(resolv, resolv_debug, "RESOLV"); - - for (i = 0; nameservers[i] != NULL; i++) - g_resolv_add_nameserver(resolv, nameservers[i], 53, 0); - - return __connman_timeserver_sync(service); -} - -static void timeserver_stop() -{ - DBG(" "); - - if (resolv != NULL) { - g_resolv_unref(resolv); - resolv = NULL; - } - - if (ts_list != NULL) - g_slist_free_full(ts_list, g_free); - - ts_list = NULL; - - __connman_ntp_stop(); + return driver->remove(server); } -int __connman_timeserver_system_set(char **servers) +void connman_timeserver_sync(void) { - save_timeservers(servers); + GSList *list; - __connman_timeserver_sync(NULL); + DBG(""); - return 0; -} + for (list = driver_list; list; list = list->next) { + struct connman_timeserver_driver *driver = list->data; -char **__connman_timeserver_system_get() -{ - char **servers; + if (driver->sync == NULL) + continue; - servers = load_timeservers(); - return servers; -} - -static void default_changed(struct connman_service *default_service) -{ - if (default_service != NULL) - timeserver_start(default_service); - else - timeserver_stop(); + driver->sync(); + } } -static struct connman_notifier timeserver_notifier = { - .name = "timeserver", - .default_changed = default_changed, -}; - int __connman_timeserver_init(void) { DBG(""); - connman_notifier_register(×erver_notifier); + server_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); return 0; } @@ -330,5 +169,5 @@ void __connman_timeserver_cleanup(void) { DBG(""); - connman_notifier_unregister(×erver_notifier); + g_hash_table_destroy(server_hash); }