aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--protocols/Makefile2
-rw-r--r--protocols/nogaim.c50
-rw-r--r--protocols/nogaim.h5
-rw-r--r--root_commands.c9
-rw-r--r--storage_xml.c21
5 files changed, 75 insertions, 12 deletions
diff --git a/protocols/Makefile b/protocols/Makefile
index b4565ab6..ae969bde 100644
--- a/protocols/Makefile
+++ b/protocols/Makefile
@@ -12,7 +12,7 @@ _SRCDIR_ := $(_SRCDIR_)protocols/
endif
# [SH] Program variables
-objects = account.o bee.o bee_chat.o bee_ft.o bee_user.o nogaim.o
+objects = account.o bee.o bee_chat.o bee_ft.o bee_user.o nogaim.o unknown.o
# [SH] The next two lines should contain the directory name (in $(subdirs))
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index d6d2e8e3..608e4d33 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -159,6 +159,7 @@ GList *get_plugins()
GList *protocols = NULL;
GList *disabled_protocols = NULL;
+static struct prpl *unknown_prpl;
void register_protocol(struct prpl *p)
{
@@ -190,11 +191,57 @@ struct prpl *find_protocol(const char *name)
return gl ? gl->data: NULL;
}
+struct prpl *make_unknown_protocol(const char *name)
+{
+ struct prpl *ret = g_memdup(unknown_prpl, sizeof(struct prpl));
+ ret->name = g_strdup(name);
+ register_protocol(ret);
+ return ret;
+}
+
gboolean is_protocol_disabled(const char *name)
{
return g_list_find_custom(disabled_protocols, name, proto_name_cmp) != NULL;
}
+/* Returns heap allocated string with text attempting to explain why a protocol is missing
+ * Free the return value with g_free() */
+char *explain_unknown_protocol(const char *name)
+{
+ char *extramsg = NULL;
+
+ if (is_protocol_disabled(name)) {
+ return g_strdup("Protocol disabled in the global config (bitlbee.conf)");
+ }
+
+ if (strcmp(name, "yahoo") == 0) {
+ return g_strdup("The old yahoo protocol is gone, try the funyahoo++ libpurple plugin instead.");
+ }
+
+#ifdef WITH_PURPLE
+ if ((strcmp(name, "msn") == 0) ||
+ (strcmp(name, "loubserp-mxit") == 0) ||
+ (strcmp(name, "myspace") == 0)) {
+ return g_strdup("This protocol has been removed from your libpurple version.");
+ }
+
+ if (strcmp(name, "hipchat") == 0) {
+ return g_strdup("This account type isn't supported by libpurple's jabber.");
+ }
+
+#else
+ if (strcmp(name, "aim") == 0 || strcmp(name, "icq") == 0) {
+ return g_strdup("This account uses libpurple specific aliases for oscar. "
+ "Re-add the account with `account add oscar ...'");
+ }
+
+ extramsg = "If this is a libpurple plugin, you might need to install bitlbee-libpurple instead.";
+#endif
+ return g_strconcat("The protocol plugin is not installed or could not be loaded. "
+ "Use the `plugins' command to list available protocols. ",
+ extramsg, NULL);
+}
+
void nogaim_init()
{
extern void msn_initmodule();
@@ -203,6 +250,9 @@ void nogaim_init()
extern void jabber_initmodule();
extern void twitter_initmodule();
extern void purple_initmodule();
+ extern void unknown_prpl_initmodule();
+
+ unknown_prpl_initmodule(&unknown_prpl);
#ifdef WITH_MSN
msn_initmodule();
diff --git a/protocols/nogaim.h b/protocols/nogaim.h
index b5a46524..3aa89c3b 100644
--- a/protocols/nogaim.h
+++ b/protocols/nogaim.h
@@ -158,6 +158,9 @@ typedef enum {
/* The protocol is not suitable for OTR, see OPT_NOOTR */
PRPL_OPT_NOOTR = 1 << 12,
+
+ /* This prpl is a placeholder for a missing protocol */
+ PRPL_OPT_UNKNOWN_PROTOCOL = 1 << 13,
} prpl_options_t;
struct prpl {
@@ -320,6 +323,8 @@ G_MODULE_EXPORT GList *get_protocols_disabled();
G_MODULE_EXPORT GSList *get_connections();
G_MODULE_EXPORT struct prpl *find_protocol(const char *name);
G_MODULE_EXPORT gboolean is_protocol_disabled(const char *name);
+G_MODULE_EXPORT struct prpl *make_unknown_protocol(const char *name);
+G_MODULE_EXPORT char *explain_unknown_protocol(const char *name);
/* When registering a new protocol, you should allocate space for a new prpl
* struct, initialize it (set the function pointers to point to your
* functions), finally call this function. */
diff --git a/root_commands.c b/root_commands.c
index 732949d8..1bbd1722 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -438,11 +438,10 @@ static void cmd_account(irc_t *irc, char **cmd)
prpl = find_protocol(cmd[2]);
if (prpl == NULL) {
- if (is_protocol_disabled(cmd[2])) {
- irc_rootmsg(irc, "Protocol disabled in global config");
- } else {
- irc_rootmsg(irc, "Unknown protocol");
- }
+ char *msg = explain_unknown_protocol(cmd[2]);
+ irc_rootmsg(irc, "Unknown protocol");
+ irc_rootmsg(irc, msg);
+ g_free(msg);
return;
}
diff --git a/storage_xml.c b/storage_xml.c
index 20f3fe3c..07cdaf0f 100644
--- a/storage_xml.c
+++ b/storage_xml.c
@@ -59,7 +59,7 @@ static void xml_init(void)
}
}
-static void handle_settings(struct xt_node *node, set_t **head)
+static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unknowns)
{
struct xt_node *c;
struct set *s;
@@ -72,6 +72,13 @@ static void handle_settings(struct xt_node *node, set_t **head)
continue;
}
+ if (add_unknowns && !set_find(head, name)) {
+ s = set_add(head, name, NULL, NULL, NULL);
+ s->flags |= ACC_SET_ONLINE_ONLY;
+ s->value = g_strdup(c->text);
+ continue;
+ }
+
if (strcmp(node->name, "account") == 0) {
set_t *s = set_find(head, name);
if (s && (s->flags & ACC_SET_ONLINE_ONLY)) {
@@ -98,6 +105,7 @@ static xt_status handle_account(struct xt_node *node, gpointer data)
struct prpl *prpl = NULL;
account_t *acc;
struct xt_node *c;
+ gboolean is_unknown = FALSE;
handle = xt_find_attr(node, "handle");
pass_b64 = xt_find_attr(node, "password");
@@ -110,9 +118,10 @@ static xt_status handle_account(struct xt_node *node, gpointer data)
if (protocol) {
prpl = find_protocol(protocol);
if (!prpl) {
- irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol);
- return XT_ABORT;
+ irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol);
+ prpl = make_unknown_protocol(protocol);
}
+ is_unknown = (prpl->options & PRPL_OPT_UNKNOWN_PROTOCOL) != 0;
local = protocol_account_islocal(protocol);
}
@@ -152,7 +161,7 @@ static xt_status handle_account(struct xt_node *node, gpointer data)
g_free(pass_cr);
g_free(password);
- handle_settings(node, &acc->set);
+ handle_settings(node, &acc->set, is_unknown);
for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) {
char *handle, *nick;
@@ -191,7 +200,7 @@ static xt_status handle_channel(struct xt_node *node, gpointer data)
set_setstr(&ic->set, "type", type);
}
- handle_settings(node, &ic->set);
+ handle_settings(node, &ic->set, FALSE);
return XT_HANDLED;
}
@@ -269,7 +278,7 @@ static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const cha
ret = STORAGE_OK;
}
- handle_settings(node, &xd->irc->b->set);
+ handle_settings(node, &xd->irc->b->set, FALSE);
error:
xt_free(xp);