summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2010-06-01 01:58:17 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2010-06-01 02:06:09 +0200
commit40ee49bad468402fa7242801979a392152a039c6 (patch)
tree2c00bc74a58131f88b8c2c177f8046e4baa81122
parentec6dc19bbeb4c93e951ba5419ccf6768d5811ae6 (diff)
downloadconnman-40ee49bad468402fa7242801979a392152a039c6.tar.gz
connman-40ee49bad468402fa7242801979a392152a039c6.tar.bz2
connman-40ee49bad468402fa7242801979a392152a039c6.zip
Fix timeserver API
We want to keep the server pointer constant.
-rw-r--r--include/timeserver.h8
-rw-r--r--plugins/ntpd.c97
-rw-r--r--src/timeserver.c15
3 files changed, 101 insertions, 19 deletions
diff --git a/include/timeserver.h b/include/timeserver.h
index f1b5c9c8..cb1ac9c9 100644
--- a/include/timeserver.h
+++ b/include/timeserver.h
@@ -32,15 +32,15 @@ extern "C" {
* @short_description: Functions for handling time servers (including NTP)
*/
-int connman_timeserver_append(char *server);
-int connman_timeserver_remove(char *server);
+int connman_timeserver_append(const char *server);
+int connman_timeserver_remove(const char *server);
void connman_timeserver_sync(void);
struct connman_timeserver_driver {
const char *name;
int priority;
- int (*append) (char *server);
- int (*remove) (char *server);
+ int (*append) (const char *server);
+ int (*remove) (const char *server);
void (*sync) (void);
};
diff --git a/plugins/ntpd.c b/plugins/ntpd.c
index ce140276..2ab30721 100644
--- a/plugins/ntpd.c
+++ b/plugins/ntpd.c
@@ -47,12 +47,42 @@ static GList *pending_peers = NULL;
#define NTPD_PORT 123
#define DEFAULT_NTP_PEER "ntp.meego.com"
+struct ntpd_peer {
+ char *server;
+ gint refcount;
+};
+
struct ntpdate_task {
struct connman_task *task;
gint conf_fd;
char *conf_path;
};
+static struct ntpd_peer *find_peer(GList *peer_list, const char* server)
+{
+ GList *list;
+ struct ntpd_peer *peer;
+
+ for (list = peer_list; list; list = list->next) {
+ peer = list->data;
+
+ if (g_str_equal(peer->server, server))
+ return peer;
+ }
+
+ return NULL;
+}
+
+static void remove_peer(GList *peer_list, struct ntpd_peer *peer)
+{
+ if (!g_atomic_int_dec_and_test(&peer->refcount))
+ return;
+
+ g_free(peer->server);
+ g_free(peer);
+ peer_list = g_list_remove(peer_list, peer);
+}
+
static connman_bool_t ntpd_running(void)
{
int sock;
@@ -113,6 +143,7 @@ static int ntpdate(void)
int err;
GError *g_err;
GList *list;
+ struct ntpd_peer *peer;
struct ntpdate_task *ntpdate;
DBG("");
@@ -146,11 +177,17 @@ static int ntpdate(void)
if (pending_peers == NULL && peers == NULL)
ntpdate_add_peer(ntpdate, DEFAULT_NTP_PEER);
- for (list = pending_peers; list; list = list->next)
- ntpdate_add_peer(ntpdate, list->data);
+ for (list = pending_peers; list; list = list->next) {
+ peer = list->data;
+
+ ntpdate_add_peer(ntpdate, peer->server);
+ }
+
+ for (list = peers; list; list = list->next) {
+ peer = list->data;
- for (list = peers; list; list = list->next)
- ntpdate_add_peer(ntpdate, list->data);
+ ntpdate_add_peer(ntpdate, peer->server);
+ }
close(ntpdate->conf_fd);
@@ -188,9 +225,9 @@ static void ntpd_sync(void)
list = g_list_first(pending_peers);
while(list) {
- char *peer = list->data;
+ struct ntpd_peer *peer = list->data;
- err = ntpd_add_peer(peer);
+ err = ntpd_add_peer(peer->server);
if (err)
continue;
@@ -202,23 +239,61 @@ static void ntpd_sync(void)
};
}
-static int ntpd_append(char *server)
+static int ntpd_append(const char *server)
{
+ struct ntpd_peer *peer;
+
DBG("");
- pending_peers = g_list_prepend(pending_peers, server);
+ if (server == NULL)
+ return 0;
+
+ if ((peer = find_peer(pending_peers, server)) ||
+ (peer = find_peer(peers, server))) {
+ g_atomic_int_inc(&peer->refcount);
+ return 0;
+ }
+
+ peer = g_try_new0(struct ntpd_peer, 1);
+ if (peer == NULL)
+ return -ENOMEM;
+
+ peer->server = g_strdup(server);
+ if (peer->server == NULL) {
+ g_free(peer);
+ return -ENOMEM;
+ }
+
+ peer->refcount = 1;
+
+ pending_peers = g_list_prepend(pending_peers, peer);
return 0;
}
-static int ntpd_remove(char *server)
+static int ntpd_remove(const char *server)
{
+ struct ntpd_peer *peer;
+
DBG("");
- peers = g_list_remove(peers, server);
+ if (server == NULL)
+ return 0;
+
+ peer = find_peer(peers, server);
+ if (peer == NULL)
+ goto remove;
+
+ remove_peer(peers, peer);
+
+remove:
/* TODO: send ntpd remove command */
- pending_peers = g_list_remove(pending_peers, server);
+ peer = find_peer(pending_peers, server);
+ if (peer == NULL)
+ return 0;
+
+ remove_peer(pending_peers, peer);
return 0;
}
diff --git a/src/timeserver.c b/src/timeserver.c
index bca66f3a..584be263 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -75,7 +75,7 @@ void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driv
*
* Append time server server address to current list
*/
-int connman_timeserver_append(char *server)
+int connman_timeserver_append(const char *server)
{
GSList *list;
@@ -90,12 +90,17 @@ int connman_timeserver_append(char *server)
for (list = driver_list; list; list = list->next) {
struct connman_timeserver_driver *driver = list->data;
+ char *new_server;
if (driver->append == NULL)
continue;
+ new_server = g_strdup(server);
+ if (new_server == NULL)
+ return -ENOMEM;
+
if (driver->append(server) == 0) {
- g_hash_table_insert(server_hash, server, driver);
+ g_hash_table_insert(server_hash, new_server, driver);
return 0;
}
}
@@ -109,7 +114,7 @@ int connman_timeserver_append(char *server)
*
* Remover time server server address from current list
*/
-int connman_timeserver_remove(char *server)
+int connman_timeserver_remove(const char *server)
{
struct connman_timeserver_driver *driver;
@@ -122,6 +127,8 @@ int connman_timeserver_remove(char *server)
if (driver == NULL)
return -EINVAL;
+ g_hash_table_remove(server_hash, server);
+
if (driver->remove == NULL)
return -ENOENT;
@@ -149,7 +156,7 @@ int __connman_timeserver_init(void)
DBG("");
server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, NULL);
+ g_free, NULL);
return 0;
}