From: Thadeu Lima de Souza Cascardo Date: Wed, 9 Oct 2013 11:16:25 +0000 (-0300) Subject: Add socket and message. X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Ff2fchat.git;a=commitdiff_plain;h=d3c08160a68a7a38468ddbe4cffafb98de177823 Add socket and message. Create a socket to send and receive messages from. --- diff --git a/f2fchat.c b/f2fchat.c index 00c774f..854a56e 100644 --- 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); diff --git a/friend.c b/friend.c index dc0f25e..de5ffdb 100644 --- a/friend.c +++ b/friend.c @@ -23,6 +23,8 @@ #include #include #include +#include +#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; }; diff --git a/friend.h b/friend.h index 844e196..3c70741 100644 --- a/friend.h +++ b/friend.h @@ -19,6 +19,10 @@ #ifndef _FRIEND_H #define _FRIEND_H +#include + +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 index 0000000..7c73006 --- /dev/null +++ b/message.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2013 Thadeu Lima de Souza Cascardo + * + * 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 +#include + +#include + +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 index 0000000..80ed923 --- /dev/null +++ b/message.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Thadeu Lima de Souza Cascardo + * + * 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