X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Ff2fchat.git;a=blobdiff_plain;f=friend.c;h=60569c1e9cb645ad10d3e429a7a924c36a21ccec;hp=68deccdf67b681c70ef9ae7fabc9c97af3c1866e;hb=HEAD;hpb=123b3a7a3989a0f040da5cc16f997ff5961fe593 diff --git a/friend.c b/friend.c index 68deccd..60569c1 100644 --- a/friend.c +++ b/friend.c @@ -26,12 +26,20 @@ #include #include #include "message.h" +#include "menu.h" + +enum { + STATE_OFFLINE, + STATE_PINGED, + STATE_ONLINE, +}; struct friend { char *name; char *address; uint16_t port; GInetSocketAddress *saddr; + int state; }; static GSocket *usock; @@ -64,12 +72,86 @@ int friend_send_message(struct friend *friend, char *buffer, size_t len) return 0; } +void friend_timeout(struct friend *friend) +{ + if (friend->state == STATE_PINGED) { + friend->state = STATE_OFFLINE; + } +} + +void friend_got_message(struct friend *friend, char *buffer, size_t len) +{ + if (len >= 4 && !strncmp(buffer, "PING", 4)) { + friend->state = STATE_ONLINE; + pong(friend); + } else if (len >= 4 && !strncmp(buffer, "PONG", 4)) { + friend->state = STATE_ONLINE; + } +} + +static void friend_list(gchar **args, GSocketAddress *address); +static void friend_add(gchar **args, GSocketAddress *address); + +struct menu_item cmds[] = { + { "list", friend_list }, + { "add", friend_add }, +}; + +void friend_cmd(gchar **args, GSocketAddress *address) +{ + int i; + if (args[1] == NULL) + return; + for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); i++) { + if (!strcmp(args[1], cmds[i].cmd)) { + cmds[i].func(args, address); + } + } +} + +void friend_init(void) +{ + struct menu_item *mi; + mi = g_malloc(sizeof(*mi)); + mi->cmd = "friend"; + mi->func = friend_cmd; + menu_add(mi); +} + struct cache { GList *friends; }; static struct cache *ucache; +static void friend_list(gchar **args, GSocketAddress *address) +{ + char *buffer; + GList *l; + for (l = g_list_first(ucache->friends); l != NULL; l = g_list_next(l)) { + struct friend *friend = l->data; + buffer = g_strdup_printf("%s\n", friend->name); + g_socket_send_to(usock, address, buffer, strlen(buffer), NULL, NULL); + g_free(buffer); + } + g_socket_send_to(usock, address, buffer, 0, NULL, NULL); +} + +static void friend_add(gchar **args, GSocketAddress *address) +{ + char *name; + char *addr; + char *sport; + uint16_t port; + if (args[2] == NULL || args[3] == NULL || args[4] == NULL) + return; + name = args[2]; + addr = args[3]; + sport = args[4]; + port = atoi(sport); + cache_add_friend(ucache, name, addr, port); +} + struct friend *friend_get_by_address(GInetAddress *address, uint16_t port) { GList *l; @@ -123,6 +205,7 @@ int cache_add_friend(struct cache *cache, char *name, char *address, uint16_t po g_object_unref(addr); cache->friends = g_list_append(cache->friends, friend); ping(friend); + friend->state = STATE_PINGED; return 0; }