From 966597cb2c97b429ed9de6202b466981ad80cbba Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Mon, 7 Oct 2013 21:25:45 -0300 Subject: [PATCH] Use a GKeyFile to load the cache of friends' addresses. Unfortunately, we need a hack to save the GKeyFile. --- friend.c | 127 ++++++++++++++++++++++++------------------------------- 1 file changed, 55 insertions(+), 72 deletions(-) diff --git a/friend.c b/friend.c index 753a588..dff03e2 100644 --- a/friend.c +++ b/friend.c @@ -17,10 +17,8 @@ */ #include "friend.h" -#include -#include -#include #include +#include #include #include #include @@ -42,7 +40,7 @@ static int connect_friend(struct sockaddr **saddr, char *address, char *port) return r; } if (addresses != NULL) { - *saddr = malloc(addresses->ai_addrlen); + *saddr = g_malloc(addresses->ai_addrlen); if (!*saddr) { r = -1; } else { @@ -63,97 +61,82 @@ struct friend { }; struct cache { - int nfriends; - struct friend *friends; + GList *friends; }; int create_cache(struct cache **cache) { - *cache = malloc(sizeof(*cache)); - if (!*cache) - return -errno; - (*cache)->nfriends = 0; + *cache = g_slice_new0(struct cache); (*cache)->friends = NULL; return 0; } +static void destroy_friend(gpointer data) +{ + struct friend *friend = data; + g_free(friend->name); + g_free(friend->address); + g_free(friend->port); + g_free(friend->saddr); + g_slice_free(struct friend, friend); +} + int destroy_cache(struct cache *cache) { if (cache->friends) - free(cache->friends); - free(cache); + g_list_free_full(cache->friends, destroy_friend); + g_slice_free(struct cache, cache); } -int cache_add_friend(struct cache *cache, char *friend, char *address, char *port) +int cache_add_friend(struct cache *cache, char *name, char *address, char *port) { - struct friend *tfriend; - if (!cache->friends) { - cache->friends = malloc(sizeof(struct friend)); - cache->nfriends = 1; - } else { - struct friend *new_friends; - cache->nfriends++; - new_friends = realloc(cache->friends, cache->nfriends * sizeof(struct friend)); - if (!new_friends) { - cache->nfriends--; - return -errno; - } - cache->friends = new_friends; - } - tfriend = &cache->friends[cache->nfriends - 1]; - tfriend->name = friend; - tfriend->address = address; - tfriend->port = port; - connect_friend(&tfriend->saddr, tfriend->address, tfriend->port); + struct friend *friend; + friend = g_slice_new0(struct friend); + friend->name = g_strdup(name); + friend->address = g_strdup(address); + friend->port = g_strdup(port); + connect_friend(&friend->saddr, friend->address, friend->port); + g_list_append(cache->friends, friend); return 0; } int load_cache(struct cache *cache, char *fname) { - FILE *file; - int err = 0; - char *buffer = NULL; - size_t len = 0; - int r; - file = fopen(fname, "r"); - if (!file) - return -errno; - while ((r = getline(&buffer, &len, file)) > 0) { - char *name; - char *address; - char *port; - char *end; - name = buffer; - address = name; - while (*++address != '\t'); - *address++ = '\0'; - port = address; - while (*++port != '\t'); - *port++ = '\0'; - end = port; - while (*++end != '\n'); - *end = '\0'; - fprintf(file, "%s\t%s\t%s\n", name, address, port); - cache_add_friend(cache, strdup(name), strdup(address), strdup(port)); + GKeyFile *file; + gchar **groups; + gchar **group; + file = g_key_file_new(); + g_key_file_load_from_file(file, fname, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, NULL); + groups = g_key_file_get_groups(file, NULL); + for (group = groups; *group != NULL; group++) { + gchar *name; + gchar *address; + gchar *port; + name = g_key_file_get_value(file, *group, "name", NULL); + address = g_key_file_get_value(file, *group, "address", NULL); + port = g_key_file_get_value(file, *group, "port", NULL); + cache_add_friend(cache, name, address, port); + g_free(name); + g_free(address); + g_free(port); } -out: - fclose(file); - return err; + g_strfreev(groups); + g_key_file_free(file); + return 0; } int store_cache(struct cache *cache, char *fname) { - FILE *file; - int err = 0; - int i; - file = fopen(fname, "w"); - if (!file) - return -errno; - for (i = 0; i < cache->nfriends; i++) { - struct friend *friend = &cache->friends[i]; - fprintf(file, "%s\t%s\t%s\n", friend->name, friend->address, friend->port); + GKeyFile *file; + GList *f; + file = g_key_file_new(); + g_key_file_load_from_file(file, fname, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, NULL); + for (f = g_list_first(cache->friends); f != NULL; f = g_list_next(f)) { + struct friend *friend = f->data; + g_key_file_set_value(file, friend->name, "name", friend->name); + g_key_file_set_value(file, friend->name, "address", friend->address); + g_key_file_set_value(file, friend->name, "port", friend->port); } -out: - fclose(file); - return err; + g_key_file_free(file); + return 0; } -- 2.20.1