diff options
author | Tomasz Wasilczyk <tomkiewicz@cpw.pidgin.im> | 2012-08-15 14:58:48 +0200 |
---|---|---|
committer | Tomasz Wasilczyk <tomkiewicz@cpw.pidgin.im> | 2012-08-15 14:58:48 +0200 |
commit | 2e8cd84b74b7198c92ecff6b6c8f3445ec1208b8 (patch) | |
tree | b558802c328704cd73345ab8d2caf981470d6cc8 | |
parent | e50c9ab543d1352c20c87f8d3fa8132524200d4f (diff) | |
download | pidgin-2e8cd84b74b7198c92ecff6b6c8f3445ec1208b8.tar.gz |
Gadu-Gadu: servers history feature
-rw-r--r-- | libpurple/protocols/gg/Makefile.am | 2 | ||||
-rw-r--r-- | libpurple/protocols/gg/gg.c | 43 | ||||
-rw-r--r-- | libpurple/protocols/gg/servconn.c | 67 | ||||
-rw-r--r-- | libpurple/protocols/gg/servconn.h | 13 | ||||
-rw-r--r-- | libpurple/protocols/gg/utils.c | 82 | ||||
-rw-r--r-- | libpurple/protocols/gg/utils.h | 12 |
6 files changed, 211 insertions, 8 deletions
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am index 704a810113..dc4d8eec75 100644 --- a/libpurple/protocols/gg/Makefile.am +++ b/libpurple/protocols/gg/Makefile.am @@ -86,6 +86,8 @@ GGSOURCES = \ multilogon.h \ status.c \ status.h \ + servconn.c \ + servconn.h \ oauth/oauth.c \ oauth/oauth.h \ oauth/oauth-parameter.c \ diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c index ef28eda156..49e87dfacc 100644 --- a/libpurple/protocols/gg/gg.c +++ b/libpurple/protocols/gg/gg.c @@ -50,6 +50,7 @@ #include "libgadu-events.h" #include "multilogon.h" #include "status.h" +#include "servconn.h" /* Prototypes */ @@ -1200,7 +1201,12 @@ static void ggp_async_login_handler(gpointer _gc, gint fd, PurpleInputCondition break; case GG_EVENT_CONN_SUCCESS: { - purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n"); + const gchar * server_ip = ggp_ipv4_to_str( + info->session->server_addr); + purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS:" + " successfully connected to %s\n", + server_ip); + ggp_servconn_add_server(server_ip); purple_input_remove(info->inpa); info->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ, @@ -1591,7 +1597,7 @@ static void ggp_close(PurpleConnection *gc) status_msg ? GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL, status_msg)) { - struct gg_event *ev; + /*struct gg_event *ev; guint64 wait_start = ggp_microtime(), now; int sleep_time = 5000; while ((ev = gg_watch_fd(info->session)) != NULL) @@ -1603,7 +1609,8 @@ static void ggp_close(PurpleConnection *gc) break; usleep(sleep_time); sleep_time *= 2; - } + }*/ + usleep(100000); } gg_logoff(info->session); gg_free_session(info->session); @@ -2074,6 +2081,9 @@ static PurplePluginProtocolInfo prpl_info = NULL /* get_public_alias */ }; +static gboolean ggp_load(PurplePlugin *plugin); +static gboolean ggp_unload(PurplePlugin *plugin); + static PurplePluginInfo info = { PURPLE_PLUGIN_MAGIC, /* magic */ PURPLE_MAJOR_VERSION, /* major_version */ @@ -2093,8 +2103,8 @@ static PurplePluginInfo info = { "boler@sourceforge.net", /* author */ PURPLE_WEBSITE, /* homepage */ - NULL, /* load */ - NULL, /* unload */ + ggp_load, /* load */ + ggp_unload, /* unload */ NULL, /* destroy */ NULL, /* ui_info */ @@ -2132,18 +2142,20 @@ static void purple_gg_debug_handler(int level, const char * format, va_list args g_free(msg); } +static PurpleAccountOption *ggp_server_option; + static void init_plugin(PurplePlugin *plugin) { PurpleAccountOption *option; GList *encryption_options = NULL; - purple_debug_info("gg", "Loading Gadu-Gadu protocol plugin with " - "libgadu %s...\n", gg_libgadu_version()); + purple_prefs_add_none("/plugins/prpl/gg"); option = purple_account_option_string_new(_("GG server"), "gg_server", ""); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + ggp_server_option = option; #define ADD_VALUE(list, desc, v) { \ PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \ @@ -2168,8 +2180,23 @@ static void init_plugin(PurplePlugin *plugin) option); gg_debug_handler = purple_gg_debug_handler; - +} + +static gboolean ggp_load(PurplePlugin *plugin) +{ + purple_debug_info("gg", "Loading Gadu-Gadu protocol plugin with " + "libgadu %s...\n", gg_libgadu_version()); + ggp_resolver_purple_setup(); + ggp_servconn_setup(ggp_server_option); + + return TRUE; +} + +static gboolean ggp_unload(PurplePlugin *plugin) +{ + ggp_servconn_cleanup(); + return TRUE; } PURPLE_INIT_PLUGIN(gg, init_plugin, info); diff --git a/libpurple/protocols/gg/servconn.c b/libpurple/protocols/gg/servconn.c new file mode 100644 index 0000000000..ffc66836aa --- /dev/null +++ b/libpurple/protocols/gg/servconn.c @@ -0,0 +1,67 @@ +#include "servconn.h" + +#include "utils.h" + +#include <debug.h> + +#define GGP_SERVCONN_HISTORY_PREF "/plugins/prpl/gg/server_history" +#define GGP_SERVCONN_HISTORY_MAXLEN 15 + +typedef struct +{ + GList *server_history; + PurpleAccountOption *server_option; +} ggp_servconn_global_data; + +static ggp_servconn_global_data global_data; + +void ggp_servconn_setup(PurpleAccountOption *server_option) +{ + purple_prefs_add_string(GGP_SERVCONN_HISTORY_PREF, ""); + + global_data.server_option = server_option; + global_data.server_history = ggp_strsplit_list(purple_prefs_get_string( + GGP_SERVCONN_HISTORY_PREF), ";", GGP_SERVCONN_HISTORY_MAXLEN + 1); + global_data.server_history = ggp_list_truncate( + global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN, + g_free); + + purple_account_option_string_set_hints(global_data.server_option, + ggp_servconn_get_servers()); +} + +void ggp_servconn_cleanup(void) +{ + g_list_free_full(global_data.server_history, &g_free); +} + +void ggp_servconn_add_server(const gchar *server) +{ + GList *old_entry; + + old_entry = g_list_find_custom(global_data.server_history, server, + (GCompareFunc)g_strcmp0); + if (old_entry) + { + g_free(old_entry->data); + global_data.server_history = g_list_delete_link( + global_data.server_history, old_entry); + } + + global_data.server_history = g_list_prepend(global_data.server_history, + g_strdup(server)); + global_data.server_history = ggp_list_truncate( + global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN, + g_free); + + purple_prefs_set_string(GGP_SERVCONN_HISTORY_PREF, ggp_strjoin_list(";", + global_data.server_history)); + purple_account_option_string_set_hints(global_data.server_option, + ggp_servconn_get_servers()); +} + +GSList * ggp_servconn_get_servers(void) +{ + return ggp_list_copy_to_slist_deep(global_data.server_history, + (GCopyFunc)g_strdup, NULL); +} diff --git a/libpurple/protocols/gg/servconn.h b/libpurple/protocols/gg/servconn.h new file mode 100644 index 0000000000..2778b1f839 --- /dev/null +++ b/libpurple/protocols/gg/servconn.h @@ -0,0 +1,13 @@ +#ifndef _GGP_SERVCONN_H +#define _GGP_SERVCONN_H + +#include <internal.h> +#include <accountopt.h> + +void ggp_servconn_setup(PurpleAccountOption *server_option); +void ggp_servconn_cleanup(void); + +void ggp_servconn_add_server(const gchar *server); +GSList * ggp_servconn_get_servers(void); + +#endif /* _GGP_SERVCONN_H */ diff --git a/libpurple/protocols/gg/utils.c b/libpurple/protocols/gg/utils.c index 0a5ad6ffa0..783929d268 100644 --- a/libpurple/protocols/gg/utils.c +++ b/libpurple/protocols/gg/utils.c @@ -127,3 +127,85 @@ gchar * ggp_utf8_strndup(const gchar *str, gsize n) return g_strndup(str, raw_len); } + +GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func, + gpointer user_data) +{ + GSList *new_list = NULL; + GList *it; + + it = g_list_first(list); + while (it) + { + new_list = g_slist_append(new_list, func(it->data, user_data)); + it = g_list_next(it); + } + return new_list; +} + +GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter, + gint max_tokens) +{ + gchar **splitted, **it; + GList *list = NULL; + + it = splitted = g_strsplit(string, delimiter, max_tokens); + while (*it) + { + list = g_list_append(list, *it); + it++; + } + g_free(splitted); + + return list; +} + +gchar * ggp_strjoin_list(const gchar *separator, GList *list) +{ + gchar **str_array; + gchar *joined; + gint list_len, i; + GList *it; + + list_len = g_list_length(list); + str_array = g_new(gchar*, list_len + 1); + + it = g_list_first(list); + i = 0; + while (it) + { + str_array[i++] = it->data; + it = g_list_next(it); + } + str_array[i] = NULL; + + joined = g_strjoinv(separator, str_array); + g_free(str_array); + + return joined; +} + +const gchar * ggp_ipv4_to_str(uint32_t raw_ip) +{ + static gchar buff[INET_ADDRSTRLEN]; + buff[0] = '\0'; + + g_snprintf(buff, sizeof(buff), "%d.%d.%d.%d", + ((raw_ip >> 0) & 0xFF), + ((raw_ip >> 8) & 0xFF), + ((raw_ip >> 16) & 0xFF), + ((raw_ip >> 24) & 0xFF)); + + return buff; +} + +GList * ggp_list_truncate(GList *list, gint length, GDestroyNotify free_func) +{ + while (g_list_length(list) > length) + { + GList *last = g_list_last(list); + free_func(last->data); + list = g_list_delete_link(list, last); + } + return list; +} diff --git a/libpurple/protocols/gg/utils.h b/libpurple/protocols/gg/utils.h index d993a9996b..12b2ed63ca 100644 --- a/libpurple/protocols/gg/utils.h +++ b/libpurple/protocols/gg/utils.h @@ -70,4 +70,16 @@ guint64 ggp_microtime(void); gchar * ggp_utf8_strndup(const gchar *str, gsize n); +GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func, + gpointer user_data); + +GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter, + gint max_tokens); + +gchar * ggp_strjoin_list(const gchar *separator, GList *list); + +const gchar * ggp_ipv4_to_str(uint32_t raw_ip); + +GList * ggp_list_truncate(GList *list, gint length, GDestroyNotify free_func); + #endif /* _GGP_UTILS_H */ |