diff options
-rw-r--r-- | irc_im.c | 2 | ||||
-rw-r--r-- | protocols/Makefile | 2 | ||||
-rw-r--r-- | protocols/account.c | 5 | ||||
-rw-r--r-- | protocols/nogaim.c | 12 | ||||
-rw-r--r-- | protocols/nogaim.h | 4 | ||||
-rw-r--r-- | protocols/unknown.c | 75 | ||||
-rw-r--r-- | root_commands.c | 19 | ||||
-rw-r--r-- | storage.c | 4 | ||||
-rw-r--r-- | storage.h | 2 | ||||
-rw-r--r-- | storage_xml.c | 53 |
10 files changed, 67 insertions, 111 deletions
@@ -1034,7 +1034,7 @@ static char *set_eval_room_account(set_t *set, char *value) if (!(acc = account_get(ic->irc->b, value))) { return SET_INVALID; - } else if (!acc->prpl->chat_join) { + } else if (!acc->prpl->chat_join && acc->prpl != &protocol_missing) { irc_rootmsg(ic->irc, "Named chatrooms not supported on that account."); return SET_INVALID; } diff --git a/protocols/Makefile b/protocols/Makefile index ae969bde..b4565ab6 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 unknown.o +objects = account.o bee.o bee_chat.o bee_ft.o bee_user.o nogaim.o # [SH] The next two lines should contain the directory name (in $(subdirs)) diff --git a/protocols/account.c b/protocols/account.c index aa14b0c3..aa1ffe61 100644 --- a/protocols/account.c +++ b/protocols/account.c @@ -77,6 +77,11 @@ account_t *account_add(bee_t *bee, struct prpl *prpl, char *user, char *pass) set_add(&a->set, "offline_user_quits", "true", set_eval_bool, a); set_add(&a->set, "offline_is_away", "false", set_eval_bool, a); + if (prpl == &protocol_missing) { + s = set_add(&a->set, "server", NULL, set_eval_account, a); + s->flags |= SET_NOSAVE | SET_HIDDEN | ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; + } + /* Hardcode some more clever tag guesses. */ strcpy(tag, prpl->name); if (strcmp(prpl->name, "oscar") == 0) { diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 18967e67..5035a156 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -159,7 +159,6 @@ GList *get_plugins() GList *protocols = NULL; GList *disabled_protocols = NULL; -static struct prpl *unknown_prpl; void register_protocol(struct prpl *p) { @@ -191,14 +190,6 @@ 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; @@ -249,9 +240,6 @@ 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 3aa89c3b..8e6c9d5a 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -158,9 +158,6 @@ 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 { @@ -323,7 +320,6 @@ 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 diff --git a/protocols/unknown.c b/protocols/unknown.c deleted file mode 100644 index 105b2f62..00000000 --- a/protocols/unknown.c +++ /dev/null @@ -1,75 +0,0 @@ -/********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2016 Wilmer van der Gaast and others * - \********************************************************************/ - -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License with - the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; - if not, write to the Free Software Foundation, Inc., 51 Franklin St., - Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#define BITLBEE_CORE -#include "nogaim.h" - -/* Displays an error when trying to connect this account */ -static void unknown_prpl_login(account_t *acc) -{ - struct im_connection *ic = imcb_new(acc); - char *msg; - - imcb_error(ic, "Unknown protocol"); - - msg = explain_unknown_protocol(acc->prpl->name); - imcb_error(ic, "%s", msg); - g_free(msg); - - imc_logout(ic, FALSE); -} - -/* Required, no-op */ -static void unknown_prpl_logout(struct im_connection *ic) -{ -} - -/* Needed to ensure the server setting is preserved */ -static void unknown_prpl_init(account_t *acc) -{ - set_t *s; - - s = set_add(&acc->set, "server", NULL, set_eval_account, acc); - s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; -} - -/* Needed to silence warnings about named groupchats not supported */ -struct groupchat *unknown_prpl_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password, - set_t **sets) -{ - return NULL; -} - -void unknown_prpl_initmodule(struct prpl **prpl) -{ - struct prpl *ret = g_new0(struct prpl, 1); - - ret->name = "unknown"; - ret->options = PRPL_OPT_UNKNOWN_PROTOCOL | PRPL_OPT_NOOTR; - ret->login = unknown_prpl_login; - ret->logout = unknown_prpl_logout; - ret->init = unknown_prpl_init; - ret->chat_join = unknown_prpl_chat_join; - *prpl = ret; -} - diff --git a/root_commands.c b/root_commands.c index 338fdf5f..b1ca8296 100644 --- a/root_commands.c +++ b/root_commands.c @@ -506,7 +506,7 @@ static void cmd_account(irc_t *irc, char **cmd) } for (a = irc->b->accounts; a; a = a->next) { - char *con; + char *con = NULL, *protocol = NULL; if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) { con = " (connected)"; @@ -518,7 +518,14 @@ static void cmd_account(irc_t *irc, char **cmd) con = ""; } - irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con); + if (a->prpl == &protocol_missing) { + protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name")); + } else { + protocol = g_strdup(a->prpl->name); + } + + irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, protocol, a->user, con); + g_free(protocol); i++; } @@ -532,7 +539,7 @@ static void cmd_account(irc_t *irc, char **cmd) irc_rootmsg(irc, "Trying to get all accounts connected..."); for (a = irc->b->accounts; a; a = a->next) { - if (!a->ic && a->auto_connect) { + if (!a->ic && a->auto_connect && a->prpl != &protocol_missing) { if (strcmp(a->pass, PASSWORD_PENDING) == 0) { irc_rootmsg(irc, "Enter password for account %s " "first (use /OPER)", a->tag); @@ -592,6 +599,12 @@ static void cmd_account(irc_t *irc, char **cmd) } else if (strcmp(a->pass, PASSWORD_PENDING) == 0) { irc_rootmsg(irc, "Enter password for account %s " "first (use /OPER)", a->tag); + } else if (a->prpl == &protocol_missing) { + char *proto = set_getstr(&a->set, "_protocol_name"); + char *msg = explain_unknown_protocol(proto); + irc_rootmsg(irc, "Unknown protocol `%s'", proto); + irc_rootmsg(irc, msg); + g_free(msg); } else { account_on(irc->b, a); } @@ -32,6 +32,10 @@ extern storage_t storage_xml; static GList *storage_backends = NULL; +const struct prpl protocol_missing = { + .name = "_unknown", +}; + void register_storage_backend(storage_t *backend) { storage_backends = g_list_append(storage_backends, backend); @@ -63,4 +63,6 @@ void storage_setup_auto_save(irc_t *irc); void register_storage_backend(storage_t *); G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate); +extern const struct prpl protocol_missing; + #endif /* __STORAGE_H__ */ diff --git a/storage_xml.c b/storage_xml.c index 07cdaf0f..a921524f 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, gboolean add_unknowns) +static void handle_settings(struct xt_node *node, set_t **head) { struct xt_node *c; struct set *s; @@ -72,13 +72,6 @@ static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unk 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)) { @@ -95,6 +88,25 @@ static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unk } } +/* Use for unsupported/not-found protocols. Save settings as-is but don't allow changes. */ +static void handle_settings_raw(struct xt_node *node, set_t **head) +{ + struct xt_node *c; + + for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) { + char *name = xt_find_attr(c, "name"); + + if (!name) { + continue; + } + + set_t *s = set_add(head, name, NULL, NULL, NULL); + set_setstr(head, name, c->text); + s->flags |= SET_HIDDEN | + ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; + } +} + static xt_status handle_account(struct xt_node *node, gpointer data) { struct xml_parsedata *xd = data; @@ -105,7 +117,6 @@ 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"); @@ -119,9 +130,8 @@ static xt_status handle_account(struct xt_node *node, gpointer data) prpl = find_protocol(protocol); if (!prpl) { irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol); - prpl = make_unknown_protocol(protocol); + prpl = (struct prpl*) &protocol_missing; } - is_unknown = (prpl->options & PRPL_OPT_UNKNOWN_PROTOCOL) != 0; local = protocol_account_islocal(protocol); } @@ -157,11 +167,20 @@ static xt_status handle_account(struct xt_node *node, gpointer data) if (locked && !g_strcasecmp(locked, "true")) { acc->flags |= ACC_FLAG_LOCKED; } + if (prpl == &protocol_missing) { + set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL); + s->flags |= SET_HIDDEN | SET_NOSAVE | + ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; + } g_free(pass_cr); g_free(password); - handle_settings(node, &acc->set, is_unknown); + if (prpl == &protocol_missing) { + handle_settings_raw(node, &acc->set); + } else { + handle_settings(node, &acc->set); + } for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) { char *handle, *nick; @@ -200,7 +219,7 @@ static xt_status handle_channel(struct xt_node *node, gpointer data) set_setstr(&ic->set, "type", type); } - handle_settings(node, &ic->set, FALSE); + handle_settings(node, &ic->set); return XT_HANDLED; } @@ -278,7 +297,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, FALSE); + handle_settings(node, &xd->irc->b->set); error: xt_free(xp); @@ -350,7 +369,11 @@ struct xt_node *xml_generate(irc_t *irc) } cur = xt_new_node("account", NULL, NULL); - xt_add_attr(cur, "protocol", acc->prpl->name); + if (acc->prpl == &protocol_missing) { + xt_add_attr(cur, "protocol", set_getstr(&acc->set, "_protocol_name")); + } else { + xt_add_attr(cur, "protocol", acc->prpl->name); + } xt_add_attr(cur, "handle", acc->user); xt_add_attr(cur, "password", pass_b64); xt_add_attr(cur, "autoconnect", acc->auto_connect ? "true" : "false"); |