/soc/2013/ankitkv/gobjectification: c61b6dbc1f03: Make protocols...
Ankit Vani
a at nevitus.org
Tue Sep 3 14:55:13 EDT 2013
Changeset: c61b6dbc1f03e3b11c4bfdb0f27e59ffd8e1fd2f
Author: Ankit Vani <a at nevitus.org>
Date: 2013-09-04 00:25 +0530
Branch: soc.2013.gobjectification.plugins
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/c61b6dbc1f03
Description:
Make protocols unregister their commands when being removed
diffstat:
libpurple/protocols/irc/irc.c | 7 +-
libpurple/protocols/irc/irc.h | 1 +
libpurple/protocols/irc/parse.c | 15 +++-
libpurple/protocols/msn/msn.c | 11 ++-
libpurple/protocols/null/nullprotocol.c | 29 ++++++-
libpurple/protocols/silc/silc.c | 132 ++++++++++++++++++++++++-------
libpurple/protocols/yahoo/libyahoo.c | 31 ++++++-
libpurple/protocols/yahoo/libyahoojp.c | 38 +++++++-
libpurple/protocols/zephyr/zephyr.c | 83 +++++++++++++-------
9 files changed, 267 insertions(+), 80 deletions(-)
diffs (truncated from 787 to 300 lines):
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -977,6 +977,11 @@ irc_protocol_base_init(IRCProtocolClass
irc_register_commands();
}
+static void irc_protocol_base_finalize(IRCProtocolClass *klass)
+{
+ irc_unregister_commands();
+}
+
static void
irc_protocol_interface_init(PurpleProtocolInterface *iface)
{
@@ -1008,8 +1013,6 @@ irc_protocol_interface_init(PurpleProtoc
iface->get_max_message_size = irc_get_max_message_size;
}
-static void irc_protocol_base_finalize(IRCProtocolClass *klass) { }
-
static PurplePluginInfo *
plugin_query(GError **error)
{
diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h
--- a/libpurple/protocols/irc/irc.h
+++ b/libpurple/protocols/irc/irc.h
@@ -150,6 +150,7 @@ const char *irc_nick_skip_mode(struct ir
gboolean irc_ischannel(const char *string);
void irc_register_commands(void);
+void irc_unregister_commands(void);
void irc_msg_table_build(struct irc_conn *irc);
void irc_parse_msg(struct irc_conn *irc, char *input);
char *irc_parse_ctcp(struct irc_conn *irc, const char *from, const char *to, const char *msg, int notice);
diff --git a/libpurple/protocols/irc/parse.c b/libpurple/protocols/irc/parse.c
--- a/libpurple/protocols/irc/parse.c
+++ b/libpurple/protocols/irc/parse.c
@@ -34,6 +34,8 @@
#include <stdlib.h>
#include <ctype.h>
+static GSList *cmds = NULL;
+
static char *irc_send_convert(struct irc_conn *irc, const char *string);
static char *irc_recv_convert(struct irc_conn *irc, const char *string);
@@ -195,6 +197,7 @@ static PurpleCmdRet irc_parse_purple_cmd
static void irc_register_command(struct _irc_user_cmd *c)
{
+ PurpleCmdId id;
PurpleCmdFlag f;
char args[10];
char *format;
@@ -221,8 +224,9 @@ static void irc_register_command(struct
args[i] = '\0';
- purple_cmd_register(c->name, args, PURPLE_CMD_P_PROTOCOL, f, "irc",
+ id = purple_cmd_register(c->name, args, PURPLE_CMD_P_PROTOCOL, f, "irc",
irc_parse_purple_cmd, _(c->help), NULL);
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
}
void irc_register_commands(void)
@@ -233,6 +237,15 @@ void irc_register_commands(void)
irc_register_command(c);
}
+void irc_unregister_commands(void)
+{
+ while (cmds) {
+ PurpleCmdId id = GPOINTER_TO_UINT(cmds->data);
+ purple_cmd_unregister(id);
+ cmds = g_slist_delete_link(cmds, cmds);
+ }
+}
+
static char *irc_send_convert(struct irc_conn *irc, const char *string)
{
char *utf8;
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
--- a/libpurple/protocols/msn/msn.c
+++ b/libpurple/protocols/msn/msn.c
@@ -97,6 +97,7 @@ typedef struct
} MsnEmoticon;
static PurpleProtocol *my_protocol = NULL;
+static GSList *cmds = NULL;
static const char *
msn_normalize(const PurpleAccount *account, const char *str)
@@ -2879,6 +2880,7 @@ msn_protocol_base_init(MsnProtocolClass
{
PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
PurpleAccountOption *option;
+ PurpleCmdId id;
proto_class->id = "msn";
proto_class->name = "MSN";
@@ -2921,10 +2923,11 @@ msn_protocol_base_init(MsnProtocolClass
proto_class->protocol_options = g_list_append(proto_class->protocol_options,
option);
- purple_cmd_register("nudge", "", PURPLE_CMD_P_PROTOCOL,
+ id = purple_cmd_register("nudge", "", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
"msn", msn_cmd_nudge,
_("nudge: nudge a user to get their attention"), NULL);
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
purple_prefs_remove("/protocols/msn");
@@ -2935,6 +2938,12 @@ msn_protocol_base_init(MsnProtocolClass
static void
msn_protocol_base_finalize(MsnProtocolClass *klass)
{
+ while (cmds) {
+ PurpleCmdId id = GPOINTER_TO_UINT(cmds->data);
+ purple_cmd_unregister(id);
+ cmds = g_slist_delete_link(cmds, cmds);
+ }
+
msn_notification_end();
msn_switchboard_end();
}
diff --git a/libpurple/protocols/null/nullprotocol.c b/libpurple/protocols/null/nullprotocol.c
--- a/libpurple/protocols/null/nullprotocol.c
+++ b/libpurple/protocols/null/nullprotocol.c
@@ -68,8 +68,19 @@
#include "util.h"
#include "version.h"
+/*
+ * reference to the protocol instance, used for registering signals, prefs,
+ * etc. it is set when the protocol is added in plugin_load and is required
+ * for removing the protocol in plugin_unload.
+ */
static PurpleProtocol *my_protocol = NULL;
+/*
+ * list of commands registered by the protocol, used to unregister the commands
+ * when the protocol is removed.
+ */
+static GSList *cmds = NULL;
+
#define NULL_STATUS_ONLINE "online"
#define NULL_STATUS_AWAY "away"
#define NULL_STATUS_OFFLINE "offline"
@@ -86,7 +97,8 @@ typedef struct {
/*
* stores offline messages that haven't been delivered yet. maps username
- * (char *) to GList * of GOfflineMessages. initialized in plugin_load.
+ * (char *) to GList * of GOfflineMessages. initialized in
+ * null_protocol_base_init.
*/
GHashTable* goffline_messages = NULL;
@@ -1057,6 +1069,7 @@ null_protocol_base_init(NullProtocolClas
PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
PurpleAccountUserSplit *split;
PurpleAccountOption *option;
+ PurpleCmdId id;
proto_class->id = "null";
proto_class->name = "Null - Testing Protocol";
@@ -1068,7 +1081,7 @@ null_protocol_base_init(NullProtocolClas
128, /* max_width */
128, /* max_height */
10000, /* max_filesize */
- PURPLE_ICON_SCALE_DISPLAY, /* scale_rules */
+ PURPLE_ICON_SCALE_DISPLAY /* scale_rules */
);
/* see accountopt.h for information about user splits and protocol options */
@@ -1087,7 +1100,7 @@ null_protocol_base_init(NullProtocolClas
proto_class->protocol_options = g_list_append(NULL, option);
/* register whisper chat command, /msg */
- purple_cmd_register("msg",
+ id = purple_cmd_register("msg",
"ws", /* args: recipient and message */
PURPLE_CMD_P_DEFAULT, /* priority */
PURPLE_CMD_FLAG_CHAT,
@@ -1096,6 +1109,9 @@ null_protocol_base_init(NullProtocolClas
"msg <username> <message>: send a private message, aka a whisper",
NULL); /* userdata */
+ /* add /msg command to the commands list */
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
/* get ready to store offline messages */
goffline_messages = g_hash_table_new_full(g_str_hash, /* hash fn */
g_str_equal, /* key comparison fn */
@@ -1107,6 +1123,13 @@ static void
null_protocol_base_finalize(NullProtocolClass *klass)
{
purple_debug_info("nullprotocol", "shutting down\n");
+
+ /* unregister the commands */
+ while (cmds) {
+ PurpleCmdId id = GPOINTER_TO_UINT(cmds->data);
+ purple_cmd_unregister(id);
+ cmds = g_slist_delete_link(cmds, cmds);
+ }
}
/*
diff --git a/libpurple/protocols/silc/silc.c b/libpurple/protocols/silc/silc.c
--- a/libpurple/protocols/silc/silc.c
+++ b/libpurple/protocols/silc/silc.c
@@ -27,7 +27,9 @@
#include "core.h"
extern SilcClientOperations ops;
+
static PurpleProtocol *my_protocol = NULL;
+static GSList *cmds = NULL;
/* Error log message callback */
@@ -1915,125 +1917,192 @@ static PurpleCmdRet silcpurple_cmd_call(
static void
silcpurple_register_commands(void)
{
- purple_cmd_register("part", "w", PURPLE_CMD_P_PROTOCOL,
+ PurpleCmdId id;
+
+ id = purple_cmd_register("part", "w", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
"silc", silcpurple_cmd_chat_part, _("part [channel]: Leave the chat"), NULL);
- purple_cmd_register("leave", "w", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("leave", "w", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
"silc", silcpurple_cmd_chat_part, _("leave [channel]: Leave the chat"), NULL);
- purple_cmd_register("topic", "s", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("topic", "s", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc",
silcpurple_cmd_chat_topic, _("topic [<new topic>]: View or change the topic"), NULL);
- purple_cmd_register("join", "ws", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("join", "ws", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
"silc", silcpurple_cmd_chat_join,
_("join <channel> [<password>]: Join a chat on this network"), NULL);
- purple_cmd_register("list", "", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("list", "", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc",
silcpurple_cmd_chat_list, _("list: List channels on this network"), NULL);
- purple_cmd_register("whois", "w", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("whois", "w", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
"silc",
silcpurple_cmd_whois, _("whois <nick>: View nick's information"), NULL);
- purple_cmd_register("msg", "ws", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("msg", "ws", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
"silc", silcpurple_cmd_msg,
_("msg <nick> <message>: Send a private message to a user"), NULL);
- purple_cmd_register("query", "ws", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("query", "ws", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc", silcpurple_cmd_query,
_("query <nick> [<message>]: Send a private message to a user"), NULL);
- purple_cmd_register("motd", "", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("motd", "", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc", silcpurple_cmd_motd,
_("motd: View the server's Message Of The Day"), NULL);
- purple_cmd_register("detach", "", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+ id = purple_cmd_register("detach", "", PURPLE_CMD_P_PROTOCOL,
PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
"silc", silcpurple_cmd_detach,
_("detach: Detach this session"), NULL);
- purple_cmd_register("quit", "s", PURPLE_CMD_P_PROTOCOL,
+ cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
More information about the Commits
mailing list