Add the friend cache.
authorThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Sun, 6 Oct 2013 03:02:56 +0000 (00:02 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Sun, 6 Oct 2013 03:02:56 +0000 (00:02 -0300)
The cache has a list of friends with its respective last seen address.

Makefile.am
f2fchat.c
friend.c [new file with mode: 0644]
friend.h [new file with mode: 0644]

index 063c512..b5b7499 100644 (file)
@@ -1,2 +1,2 @@
 bin_PROGRAMS = f2fchat
-f2fchat_SOURCES = f2fchat.c
+f2fchat_SOURCES = f2fchat.c friend.c
index 711811c..55bdc5a 100644 (file)
--- a/f2fchat.c
+++ b/f2fchat.c
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include "friend.h"
+
 int main(int argc, char **argv)
 {
+       struct cache *cache;
+       int out = 0;
+       create_cache(&cache);
+       load_cache(cache, "friends.cache");
+       while (!out) {
+               out = 1;
+       }
+       store_cache(cache, "friends.cache");
+       destroy_cache(cache);
        return 0;
 }
diff --git a/friend.c b/friend.c
new file mode 100644 (file)
index 0000000..58e7bc5
--- /dev/null
+++ b/friend.c
@@ -0,0 +1,162 @@
+/*
+ *  Copyright (C) 2013  Thadeu Lima de Souza Cascardo <cascardo@cascardo.info>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "friend.h"
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+static int connect_friend(struct sockaddr *saddr, char *address, char *port, int *c)
+{
+       struct addrinfo *addresses;
+       struct addrinfo *addr;
+       struct addrinfo hint;
+       int r;
+       int fd = *c = -1;
+       int i;
+       memset(&hint, 0, sizeof(hint));
+       hint.ai_family = AF_UNSPEC;
+       hint.ai_socktype = SOCK_STREAM;
+       hint.ai_protocol = IPPROTO_TCP;
+       hint.ai_flags = AI_ADDRCONFIG;
+       r = getaddrinfo(address, port, &hint, &addresses);
+       if (r) {
+               return r;
+       }
+       for (addr = addresses; addr != NULL; addr = addr->ai_next) {
+               fd = socket(addr->ai_family, addr->ai_socktype,
+                               addr->ai_protocol);
+               if (fd >= 0)
+                       break;
+               close(fd);
+               fd = -1;
+       }
+       freeaddrinfo(addresses);
+       *c = fd;
+       if (fd == -1)
+               return EAI_SYSTEM;
+       return 0;
+}
+
+struct friend {
+       char *name;
+       char *address;
+       char *port;
+       struct sockaddr *saddr;
+};
+
+struct cache {
+       int nfriends;
+       struct friend *friends;
+};
+
+int create_cache(struct cache **cache)
+{
+       *cache = malloc(sizeof(*cache));
+       if (!*cache)
+               return -errno;
+       (*cache)->nfriends = 0;
+       (*cache)->friends = NULL;
+       return 0;
+}
+
+int destroy_cache(struct cache *cache)
+{
+       if (cache->friends)
+               free(cache->friends);
+       free(cache);
+}
+
+int cache_add_friend(struct cache *cache, char *friend, 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;
+       tfriend->saddr = NULL;
+       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));
+       }
+out:
+       fclose(file);
+       return err;
+}
+
+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);
+       }
+out:
+       fclose(file);
+       return err;
+}
diff --git a/friend.h b/friend.h
new file mode 100644 (file)
index 0000000..844e196
--- /dev/null
+++ b/friend.h
@@ -0,0 +1,30 @@
+/*
+ *  Copyright (C) 2013  Thadeu Lima de Souza Cascardo <cascardo@cascardo.info>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _FRIEND_H
+#define _FRIEND_H
+
+struct friend;
+struct cache;
+int create_cache(struct cache **cache);
+int destroy_cache(struct cache *cache);
+int cache_add_friend(struct cache *cache, char *friend, char *address, char *port);
+int load_cache(struct cache *cache, char *fname);
+int store_cache(struct cache *cache, char *fname);
+
+#endif