Add socket and message.
authorThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Wed, 9 Oct 2013 11:16:25 +0000 (08:16 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Wed, 9 Oct 2013 11:16:25 +0000 (08:16 -0300)
Create a socket to send and receive messages from.

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

index 00c774f..854a56e 100644 (file)
--- a/f2fchat.c
+++ b/f2fchat.c
@@ -30,10 +30,11 @@ int main(int argc, char **argv)
 {
        struct cache *cache;
        GMainLoop *loop;
+       g_type_init();
        create_cache(&cache);
        load_cache(cache, "friends.cache");
+       sock_init();
        loop = g_main_loop_new(g_main_context_default(), TRUE);
-       g_idle_add(quit, loop);
        g_main_loop_run(loop);
        store_cache(cache, "friends.cache");
        destroy_cache(cache);
index dc0f25e..de5ffdb 100644 (file)
--- a/friend.c
+++ b/friend.c
@@ -23,6 +23,8 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <errno.h>
+#include "message.h"
 
 static int connect_friend(struct sockaddr **saddr, char *address, char *port)
 {
@@ -60,6 +62,34 @@ struct friend {
        struct sockaddr *saddr;
 };
 
+static int usock;
+
+int sock_init(void)
+{
+       struct sockaddr_in6 sa;
+       memset(&sa, 0, sizeof(sa));
+       sa.sin6_family = AF_INET6;
+       sa.sin6_port = htons(17078);
+       memcpy((void *) &sa.sin6_addr, (void *) &in6addr_any, sizeof(in6addr_any));
+       usock = socket(AF_INET6, SOCK_DGRAM, 0);
+       bind(usock, (struct sockaddr *) &sa, sizeof(sa));
+       message_init(usock);
+       return 0;
+}
+
+int friend_send_message(struct friend *friend, char *buffer, size_t len)
+{
+       socklen_t sl;
+       if (friend->saddr->sa_family == AF_INET)
+               sl = sizeof(struct sockaddr_in);
+       else if (friend->saddr->sa_family == AF_INET6)
+               sl = sizeof(struct sockaddr_in6);
+       else
+               return -EAFNOSUPPORT;
+       sendto(usock, buffer, len, 0, friend->saddr, sl);
+       return 0;
+}
+
 struct cache {
        GList *friends;
 };
index 844e196..3c70741 100644 (file)
--- a/friend.h
+++ b/friend.h
 #ifndef _FRIEND_H
 #define _FRIEND_H
 
+#include <stdlib.h>
+
+int sock_init(void);
+
 struct friend;
 struct cache;
 int create_cache(struct cache **cache);
@@ -27,4 +31,6 @@ int cache_add_friend(struct cache *cache, char *friend, char *address, char *por
 int load_cache(struct cache *cache, char *fname);
 int store_cache(struct cache *cache, char *fname);
 
+int friend_send_message(struct friend *friend, char *buffer, size_t len);
+
 #endif
diff --git a/message.c b/message.c
new file mode 100644 (file)
index 0000000..7c73006
--- /dev/null
+++ b/message.c
@@ -0,0 +1,73 @@
+/*
+ *  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 "message.h"
+#include "friend.h"
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <stdio.h>
+
+gboolean ping_timeout(gpointer data)
+{
+       struct friend *friend = data;
+       return G_SOURCE_REMOVE;
+}
+
+static GIOChannel *uchannel;
+static GSocket *gusock;
+
+static void command(char *buffer, size_t len)
+{
+       printf("message from loopback: %d %.*s\n", len, len, buffer);
+}
+
+gboolean message_incoming(GIOChannel *channel, GIOCondition cond, gpointer data)
+{
+       size_t len;
+       char *buffer;
+       GSocketAddress *address;
+       GInetAddress *iaddress;
+       if (!gusock) {
+               gusock = g_socket_new_from_fd(g_io_channel_unix_get_fd(channel), NULL);
+       }
+       len = g_socket_get_available_bytes(gusock);
+       buffer = g_malloc(len);
+       len = g_socket_receive_from(gusock, &address, buffer, len, NULL, NULL);
+       iaddress = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(address));
+       if (g_inet_address_get_is_loopback(iaddress)) {
+               command(buffer, len);
+       }
+       g_object_unref(address);
+       g_free(buffer);
+       return TRUE;
+}
+
+int message_init(int sock)
+{
+       uchannel = g_io_channel_unix_new(sock);
+       g_io_add_watch(uchannel, G_IO_IN, message_incoming, NULL);
+       return 0;
+}
+
+int ping(struct friend *friend)
+{
+       char ping[5] = "PING";
+       friend_send_message(friend, ping, 4);
+       g_timeout_add(2000, ping_timeout, friend);
+}
diff --git a/message.h b/message.h
new file mode 100644 (file)
index 0000000..80ed923
--- /dev/null
+++ b/message.h
@@ -0,0 +1,27 @@
+/*
+ *  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 _MESSAGE_H
+#define _MESSAGE_H
+
+#include "friend.h"
+
+int message_init(int sock);
+int ping(struct friend *friend);
+
+#endif