5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <gweb/gresolv.h>
34 static GSList *driver_list = NULL;
35 static GHashTable *server_hash = NULL;
37 static char **system_timeservers = NULL;
38 static char **timeservers = NULL;
40 static GResolv *resolv = NULL;
41 static int resolv_id = 0;
42 static volatile int count;
44 static void resolv_debug(const char *str, void *data)
46 connman_info("%s: %s\n", (const char *) data, str);
48 static void save_timeservers(char **servers)
53 keyfile = __connman_storage_load_global();
55 keyfile = g_key_file_new();
57 for (cnt = 0; servers != NULL && servers[cnt] != NULL; cnt++);
59 g_key_file_set_string_list(keyfile, "global", "Timeservers",
60 (const gchar **)servers, cnt);
62 __connman_storage_save_global(keyfile);
64 g_key_file_free(keyfile);
69 static char **load_timeservers()
73 char **servers = NULL;
75 keyfile = __connman_storage_load_global();
79 servers = g_key_file_get_string_list(keyfile, "global",
80 "Timeservers", NULL, &error);
82 DBG("Error loading timeservers: %s", error->message);
86 g_key_file_free(keyfile);
91 static gint compare_priority(gconstpointer a, gconstpointer b)
93 const struct connman_timeserver_driver *driver1 = a;
94 const struct connman_timeserver_driver *driver2 = b;
96 return driver2->priority - driver1->priority;
100 * connman_timeserver_driver_register:
101 * @driver: timeserver driver definition
103 * Register a new timeserver driver
105 * Returns: %0 on success
107 int connman_timeserver_driver_register(struct connman_timeserver_driver *driver)
109 DBG("driver %p name %s", driver, driver->name);
111 driver_list = g_slist_insert_sorted(driver_list, driver,
118 * connman_timeserver_driver_unregister:
119 * @driver: timeserver driver definition
121 * Remove a previously registered timeserver driver
123 void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driver)
125 DBG("driver %p name %s", driver, driver->name);
127 driver_list = g_slist_remove(driver_list, driver);
130 /* Restart NTP procedure */
131 static void connman_timeserver_restart()
133 /* If service timeservers are in use, dont restart ntp */
134 if (timeservers != NULL)
137 if (resolv == NULL) {
138 DBG("No online service.");
142 /* Cancel current lookup */
144 g_resolv_cancel_lookup(resolv, resolv_id);
146 /* Reload system timeserver list */
147 if (system_timeservers != NULL) {
148 g_strfreev(system_timeservers);
149 system_timeservers = NULL;
152 system_timeservers = load_timeservers();
154 if (system_timeservers == NULL)
157 __connman_ntp_stop();
161 __connman_timeserver_sync_next();
164 static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data)
168 DBG("status %d", status);
170 __sync_fetch_and_add(&count, 1);
172 if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
173 if (results != NULL) {
174 for (i = 0; results[i]; i++)
175 DBG("result: %s", results[i]);
177 __connman_ntp_start(results[0]);
183 __connman_timeserver_sync_next();
186 void __connman_timeserver_sync_next()
188 if (system_timeservers == NULL ||
189 system_timeservers[count] == NULL)
192 DBG("Trying timeserver %s", system_timeservers[count]);
195 resolv_id = g_resolv_lookup_hostname(resolv,
196 system_timeservers[count], resolv_result,
200 int __connman_timeserver_sync(struct connman_service *service)
202 char **nameservers = NULL;
205 DBG("service %p", service);
207 i = __connman_service_get_index(service);
211 nameservers = connman_service_get_nameservers(service);
212 if (nameservers == NULL)
215 resolv = g_resolv_new(i);
219 if (getenv("CONNMAN_RESOLV_DEBUG"))
220 g_resolv_set_debug(resolv, resolv_debug, "RESOLV");
222 for (i = 0; nameservers[i] != NULL; i++)
223 g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);
227 system_timeservers = load_timeservers();
229 timeservers = connman_service_get_timeservers(service);
231 if (timeservers != NULL && timeservers[0] != NULL) {
232 DBG("Using service tiemservers");
233 __connman_ntp_start(timeservers[0]);
237 if (system_timeservers == NULL || system_timeservers[count] == NULL) {
238 DBG("No timeservers set.");
242 DBG("Trying server %s", system_timeservers[count]);
244 resolv_id = g_resolv_lookup_hostname(resolv, system_timeservers[count],
245 resolv_result, NULL);
249 void __connman_timeserver_stop()
253 if (resolv != NULL) {
254 g_resolv_unref(resolv);
258 if (system_timeservers != NULL) {
259 g_strfreev(system_timeservers);
260 system_timeservers = NULL;
267 __connman_ntp_stop();
270 int __connman_timeserver_system_append(const char *server)
273 char **servers = NULL;
275 if (server == NULL) {
276 save_timeservers(servers);
280 DBG("server %s", server);
282 servers = load_timeservers();
284 if (servers != NULL) {
287 for (i = 0; servers[i] != NULL; i++)
288 if (g_strcmp0(servers[i], server) == 0) {
293 len = g_strv_length(servers);
294 servers = g_try_renew(char *, servers, len + 2);
297 servers = g_try_new0(char *, len + 2);
303 servers[len] = g_strdup(server);
304 servers[len + 1] = NULL;
306 save_timeservers(servers);
310 connman_timeserver_restart();
315 int __connman_timeserver_system_remove(const char *server)
324 DBG("server %s", server);
326 servers = load_timeservers();
331 len = g_strv_length(servers);
333 if (g_strcmp0(servers[0], server) != 0) {
340 save_timeservers(servers);
344 temp = g_try_new0(char *, len - 1);
350 for (i = 0, j = 0; i < len; i++) {
351 if (g_strcmp0(servers[i], server) != 0) {
352 temp[j] = g_strdup(servers[i]);
356 temp[len - 1] = NULL;
359 servers = g_strdupv(temp);
362 save_timeservers(servers);
365 connman_timeserver_restart();
370 char **__connman_timeserver_system_get()
374 servers = load_timeservers();
378 int __connman_timeserver_init(void)
382 server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
388 void __connman_timeserver_cleanup(void)
392 g_hash_table_destroy(server_hash);