summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Wasilczyk <tomkiewicz@cpw.pidgin.im>2012-08-15 14:58:48 +0200
committerTomasz Wasilczyk <tomkiewicz@cpw.pidgin.im>2012-08-15 14:58:48 +0200
commit2e8cd84b74b7198c92ecff6b6c8f3445ec1208b8 (patch)
treeb558802c328704cd73345ab8d2caf981470d6cc8
parente50c9ab543d1352c20c87f8d3fa8132524200d4f (diff)
downloadpidgin-2e8cd84b74b7198c92ecff6b6c8f3445ec1208b8.tar.gz
Gadu-Gadu: servers history feature
-rw-r--r--libpurple/protocols/gg/Makefile.am2
-rw-r--r--libpurple/protocols/gg/gg.c43
-rw-r--r--libpurple/protocols/gg/servconn.c67
-rw-r--r--libpurple/protocols/gg/servconn.h13
-rw-r--r--libpurple/protocols/gg/utils.c82
-rw-r--r--libpurple/protocols/gg/utils.h12
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 */