aboutsummaryrefslogtreecommitdiffstats
path: root/facebook/facebook.c
diff options
context:
space:
mode:
authorjgeboski <jgeboski@gmail.com>2015-08-24 17:01:16 -0400
committerjgeboski <jgeboski@gmail.com>2015-08-24 17:01:16 -0400
commit53cedfaca78278a64cc347e8ed51bb67363b3dcc (patch)
treedd2c6cac0c3d5d4af1cccaa9cbbc7a6ca4522572 /facebook/facebook.c
parent60a42307f24c617029efbb7bcd432d162706c692 (diff)
downloadbitlbee-facebook-53cedfaca78278a64cc347e8ed51bb67363b3dcc.tar.gz
bitlbee-facebook-53cedfaca78278a64cc347e8ed51bb67363b3dcc.tar.bz2
bitlbee-facebook-53cedfaca78278a64cc347e8ed51bb67363b3dcc.tar.xz
Imported changes from purple-facebook
Diffstat (limited to 'facebook/facebook.c')
-rw-r--r--facebook/facebook.c1274
1 files changed, 608 insertions, 666 deletions
diff --git a/facebook/facebook.c b/facebook/facebook.c
index c25232e..61bc04d 100644
--- a/facebook/facebook.c
+++ b/facebook/facebook.c
@@ -15,187 +15,341 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "facebook.h"
+#include <bitlbee.h>
+
+#include "facebook-api.h"
+#include "facebook-data.h"
+#include "facebook-mqtt.h"
#include "facebook-util.h"
-/**
- * Implemented #fb_api_funcs->error().
- *
- * @param api The #fb_api.
- * @param err The #GError.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_error(fb_api_t *api, GError *err, gpointer data)
+static void
+fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data);
+
+static void
+fb_cb_api_auth(FbApi *api, gpointer data)
{
- fb_data_t *fata = data;
+ FbData *fata = data;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
- FB_UTIL_DEBUGLN("Error: %s", err->message);
- imcb_error(fata->ic, "%s", err->message);
- imc_logout(fata->ic, TRUE);
+ imcb_log(ic, "Fetching contacts");
+ fb_data_save(fata);
+ fb_api_contacts(api);
}
-/**
- * Implemented #fb_api_funcs->auth().
- *
- * @param api The #fb_api.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_auth(fb_api_t *api, gpointer data)
+static void
+fb_cb_api_connect(FbApi *api, gpointer data)
{
- fb_data_t *fata = data;
- account_t *acc = fata->ic->acc;
- gchar uid[FB_ID_STRMAX];
+ account_t *acct;
+ FbData *fata = data;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
+ acct = ic->acc;
- FB_ID_TO_STR(api->uid, uid);
- set_setstr(&acc->set, "uid", uid);
- set_setstr(&acc->set, "token", api->token);
- imcb_log(fata->ic, "Authentication finished");
+ fb_data_save(fata);
+ imcb_connected(ic);
- account_off(acc->bee, acc);
- account_on(acc->bee, acc);
+ if (set_getbool(&acct->set, "show_unread")) {
+ fb_api_unread(api);
+ }
}
-/**
- * Implemented #fb_api_funcs->connect().
- *
- * @param api The #fb_api.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_connect(fb_api_t *api, gpointer data)
+static void
+fb_cb_api_contact(FbApi *api, FbApiUser *user, gpointer data)
{
- fb_data_t *fata = data;
- account_t *acc = fata->ic->acc;
+ FbData *fata = data;
+ gchar uid[FB_ID_STRMAX];
+ GSList *msgs;
+ struct im_connection *ic;
- imcb_connected(fata->ic);
- set_setstr(&acc->set, "stoken", api->stoken);
+ ic = fb_data_get_connection(fata);
+ FB_ID_TO_STR(user->uid, uid);
+
+ if (bee_user_by_handle(ic->bee, ic, uid) == NULL) {
+ bee_user_new(ic->bee, ic, uid, BEE_USER_LOCAL);
+ imcb_buddy_nick_hint(ic, uid, user->name);
+ imcb_rename_buddy(ic, uid, user->name);
+ }
+
+ msgs = fb_data_take_messages(fata, user->uid);
+
+ if (msgs != NULL) {
+ fb_cb_api_messages(api, msgs, fata);
+ g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free);
+ }
}
-/**
- * Implemented #fb_api_funcs->contacts().
- *
- * @param api The #fb_api.
- * @param users The #GSList of #fb_api_user.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_contacts(fb_api_t *api, GSList *users, gpointer data)
+static gboolean
+fb_cb_sync_contacts(gpointer data, gint fd, b_input_condition cond)
+{
+ FbApi *api;
+ FbData *fata = data;
+
+ api = fb_data_get_api(fata);
+ fb_data_clear_timeout(fata, "sync-contacts", FALSE);
+ fb_api_contacts(api);
+ return FALSE;
+}
+
+static void
+fb_cb_api_contacts(FbApi *api, GSList *users, gboolean complete, gpointer data)
{
- fb_data_t *fata = data;
- fb_api_user_t *user;
- GSList *l;
- gchar uid[FB_ID_STRMAX];
+ account_t *acct;
+ bee_user_t *bu;
+ FbApiUser *user;
+ FbData *fata = data;
+ FbId muid;
+ gchar uid[FB_ID_STRMAX];
+ gint sync;
+ GSList *l;
+ GValue val = G_VALUE_INIT;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
+
+ g_value_init(&val, FB_TYPE_ID);
+ g_object_get_property(G_OBJECT(api), "uid", &val);
+ muid = g_value_get_int64(&val);
+ g_value_unset(&val);
for (l = users; l != NULL; l = l->next) {
user = l->data;
FB_ID_TO_STR(user->uid, uid);
- imcb_add_buddy(fata->ic, uid, NULL);
- imcb_buddy_nick_hint(fata->ic, uid, user->name);
- imcb_rename_buddy(fata->ic, uid, user->name);
+
+ if (G_UNLIKELY(user->uid == muid)) {
+ continue;
+ }
+
+ imcb_add_buddy(ic, uid, NULL);
+ imcb_buddy_nick_hint(ic, uid, user->name);
+ imcb_rename_buddy(ic, uid, user->name);
+
+ bu = imcb_buddy_by_handle(ic, uid);
+ bu->data = GINT_TO_POINTER(TRUE);
+ }
+
+ if (!complete) {
+ return;
+ }
+
+ l = ic->bee->users;
+
+ while (l != NULL) {
+ bu = l->data;
+ l = l->next;
+
+ if (bu->ic != ic) {
+ continue;
+ }
+
+ if (GPOINTER_TO_INT(bu->data)) {
+ bu->data = NULL;
+ } else {
+ imcb_remove_buddy(ic, bu->handle, NULL);
+ }
}
- imcb_log(fata->ic, "Establishing connection");
- fb_api_connect(fata->api);
+ if (!(ic->flags & OPT_LOGGED_IN)) {
+ imcb_log(ic, "Connecting");
+ fb_api_connect(api, FALSE);
+ }
+
+ acct = ic->acc;
+ sync = set_getint(&acct->set, "sync_interval");
+
+ if (sync < 5) {
+ set_setint(&acct->set, "sync_interval", 5);
+ sync = 5;
+ }
+
+ sync *= 60 * 1000;
+ fb_data_add_timeout(fata, "sync-contacts", sync, fb_cb_sync_contacts,
+ fata);
}
-/**
- * Implemented #fb_api_funcs->message().
- *
- * @param api The #fb_api.
- * @param msgs The #GSList of #fb_api_msg.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_message(fb_api_t *api, GSList *msgs, gpointer data)
+static void
+fb_cb_api_error(FbApi *api, GError *error, gpointer data)
+{
+ FbData *fata = data;
+ gboolean recon;
+ struct im_connection *ic;
+
+ if (g_error_matches(error, FB_API_ERROR, FB_API_ERROR_QUEUE)) {
+ /* Save the reset data */
+ fb_data_save(fata);
+ }
+
+ recon = ((error->domain != FB_HTTP_ERROR) ||
+ (error->code < 400) ||
+ (error->code > 500)) &&
+ !g_error_matches(error, FB_API_ERROR, FB_API_ERROR_AUTH);
+
+ ic = fb_data_get_connection(fata);
+ fb_util_debug_error("%s", error->message);
+ imcb_error(ic, "%s", error->message);
+ imc_logout(ic, recon);
+}
+
+static void
+fb_cb_api_events(FbApi *api, GSList *events, gpointer data)
{
- fb_data_t *fata = data;
- fb_api_msg_t *msg;
+ FbApiEvent *event;
+ FbData *fata = data;
+ gchar tid[FB_ID_STRMAX];
+ gchar uid[FB_ID_STRMAX];
+ GHashTable *fetch;
+ GHashTableIter iter;
+ GSList *l;
struct groupchat *gc;
- GSList *l;
- gchar uid[FB_ID_STRMAX];
- gchar tid[FB_ID_STRMAX];
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
+ fetch = g_hash_table_new(fb_id_hash, fb_id_equal);
+
+ for (l = events; l != NULL; l = l->next) {
+ event = l->data;
+
+ FB_ID_TO_STR(event->tid, tid);
+ gc = bee_chat_by_title(ic->bee, ic, tid);
+
+ if (gc == NULL) {
+ continue;
+ }
+
+ FB_ID_TO_STR(event->uid, uid);
+
+ switch (event->type) {
+ case FB_API_EVENT_TYPE_THREAD_USER_ADDED:
+ if (bee_user_by_handle(ic->bee, ic, uid) == NULL) {
+ g_hash_table_insert(fetch, &event->tid, event);
+ break;
+ }
+
+ imcb_chat_add_buddy(gc, uid);
+ break;
+
+ case FB_API_EVENT_TYPE_THREAD_USER_REMOVED:
+ imcb_chat_remove_buddy(gc, uid, NULL);
+ break;
+ }
+ }
+
+ g_hash_table_iter_init(&iter, fetch);
+
+ while (g_hash_table_iter_next(&iter, NULL, (gpointer) &event)) {
+ fb_api_thread(api, event->tid);
+ }
+
+ g_hash_table_destroy(fetch);
+}
+
+static void
+fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data)
+{
+ account_t *acct;
+ FbApiMessage *msg;
+ FbData *fata = data;
+ gboolean mark;
+ gchar tid[FB_ID_STRMAX];
+ gchar uid[FB_ID_STRMAX];
+ GSList *l;
+ struct groupchat *gc;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
+ acct = ic->acc;
+ mark = set_getbool(&acct->set, "mark_read");
for (l = msgs; l != NULL; l = l->next) {
msg = l->data;
FB_ID_TO_STR(msg->uid, uid);
+ if (msg->flags & FB_API_MESSAGE_FLAG_SELF) {
+ continue;
+ }
+
+ if (bee_user_by_handle(ic->bee, ic, uid) == NULL) {
+ msg = fb_api_message_dup(msg, TRUE);
+ fb_data_add_message(fata, msg);
+ fb_api_contact(api, msg->uid);
+ continue;
+ }
+
if (msg->tid == 0) {
- imcb_buddy_msg(fata->ic, uid, (gchar*) msg->text, 0, 0);
+ if (mark) {
+ fb_api_read(api, msg->uid, FALSE);
+ }
+
+ imcb_buddy_msg(ic, uid, (gchar*) msg->text, 0, 0);
continue;
}
FB_ID_TO_STR(msg->tid, tid);
- gc = bee_chat_by_title(fata->ic->bee, fata->ic, tid);
+ gc = bee_chat_by_title(ic->bee, ic, tid);
+
+ if (gc != NULL) {
+ if (mark) {
+ fb_api_read(api, msg->tid, TRUE);
+ }
- if (gc != NULL)
imcb_chat_msg(gc, uid, (gchar*) msg->text, 0, 0);
+ }
}
}
-/**
- * Implemented #fb_api_funcs->presence().
- *
- * @param api The #fb_api.
- * @param press The #GSList of #fb_api_msg.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_presence(fb_api_t *api, GSList *press, gpointer data)
+static void
+fb_cb_api_presences(FbApi *api, GSList *press, gpointer data)
{
- fb_data_t *fata = data;
- fb_api_pres_t *pres;
- GSList *l;
- guint flags;
- gchar uid[FB_ID_STRMAX];
+ FbApiPresence *pres;
+ FbData *fata = data;
+ gchar uid[FB_ID_STRMAX];
+ GSList *l;
+ guint flags;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
for (l = press; l != NULL; l = l->next) {
- pres = l->data;
- flags = 0;
+ pres = l->data;
+ FB_ID_TO_STR(pres->uid, uid);
- if (pres->active)
- flags |= BEE_USER_ONLINE;
+ if (bee_user_by_handle(ic->bee, ic, uid) == NULL) {
+ continue;
+ }
+
+ if (pres->active) {
+ flags = BEE_USER_ONLINE;
+ } else {
+ flags = 0;
+ }
FB_ID_TO_STR(pres->uid, uid);
- imcb_buddy_status(fata->ic, uid, flags, NULL, NULL);
+ imcb_buddy_status(ic, uid, flags, NULL, NULL);
}
}
-/**
- * Implemented #fb_api_funcs->thread_create().
- *
- * @param api The #fb_api.
- * @param tid The thread #fb_id.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_thread_create(fb_api_t *api, fb_id_t tid, gpointer data)
-{
- fb_data_t *fata = data;
- account_t *acc = fata->ic->acc;
-
- fata->tids = g_slist_prepend(fata->tids, g_memdup(&tid, sizeof tid));
- imcb_log(fata->ic, "Created chat thread %" FB_ID_FORMAT, tid);
- imcb_log(fata->ic, "Join: fbjoin %s %d <channel-name>", acc->tag, 1);
-}
-
-/**
- * Implemented #fb_api_funcs->thread_info().
- *
- * @param api The #fb_api.
- * @param thrd The #fb_api_thread.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_thread_info(fb_api_t *api, fb_api_thread_t *thrd,
- gpointer data)
+static void
+fb_cb_api_thread(FbApi *api, FbApiThread *thrd, gpointer data)
{
- fb_data_t *fata = data;
- fb_api_user_t *user;
- bee_user_t *bu;
+ bee_user_t *bu;
+ FbApiUser *user;
+ FbData *fata = data;
+ gchar id[FB_ID_STRMAX];
+ GList *h;
+ GSList *l;
+ GString *gstr;
struct groupchat *gc;
- GSList *l;
- GString *gstr;
- gchar id[FB_ID_STRMAX];
+ struct im_connection *ic;
FB_ID_TO_STR(thrd->tid, id);
- gc = bee_chat_by_title(fata->ic->bee, fata->ic, id);
+ ic = fb_data_get_connection(fata);
+ gc = bee_chat_by_title(ic->bee, ic, id);
- if (G_UNLIKELY(gc == NULL))
+ if (G_UNLIKELY(gc == NULL)) {
return;
+ }
if (thrd->topic == NULL) {
gstr = g_string_new(NULL);
@@ -203,8 +357,9 @@ static void fb_cb_api_thread_info(fb_api_t *api, fb_api_thread_t *thrd,
for (l = thrd->users; l != NULL; l = l->next) {
user = l->data;
- if (gstr->len > 0)
+ if (gstr->len > 0) {
g_string_append(gstr, ", ");
+ }
g_string_append(gstr, user->name);
}
@@ -212,220 +367,146 @@ static void fb_cb_api_thread_info(fb_api_t *api, fb_api_thread_t *thrd,
imcb_chat_topic(gc, NULL, gstr->str, 0);
g_string_free(gstr, TRUE);
} else {
- imcb_chat_topic(gc, NULL, (gchar*) thrd->topic, 0);
+ imcb_chat_topic(gc, NULL, (gchar *) thrd->topic, 0);
}
for (l = thrd->users; l != NULL; l = l->next) {
user = l->data;
FB_ID_TO_STR(user->uid, id);
- bu = bee_user_by_handle(fata->ic->bee, fata->ic, id);
+ h = g_list_find_custom(gc->in_room, id, (GCompareFunc) g_strcmp0);
- imcb_chat_add_buddy(gc, id);
+ if (h != NULL) {
+ continue;
+ }
+
+ bu = bee_user_by_handle(ic->bee, ic, id);
if (bu == NULL) {
- imcb_buddy_nick_hint(fata->ic, id, user->name);
- imcb_rename_buddy(fata->ic, id, user->name);
+ bee_user_new(ic->bee, ic, id, BEE_USER_LOCAL);
+ imcb_buddy_nick_hint(ic, id, user->name);
+ imcb_rename_buddy(ic, id, user->name);
}
+
+ imcb_chat_add_buddy(gc, id);
}
}
-/**
- * Implemented #fb_api_funcs->thread_list().
- *
- * @param api The #fb_api.
- * @param thrds The #GSList of #fb_api_thread.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_thread_list(fb_api_t *api, GSList *thrds, gpointer data)
+static void
+fb_cb_api_thread_create(FbApi *api, FbId tid, gpointer data)
{
- fb_data_t *fata = data;
- fb_api_thread_t *thrd;
- fb_api_user_t *user;
- GSList *phrds;
- GSList *l;
- GSList *m;
- GString *ln;
- gpointer mptr;
- guint i;
- guint j;
-
- g_slist_free_full(fata->tids, g_free);
- fata->tids = NULL;
- phrds = NULL;
+ account_t *acct;
+ FbData *fata = data;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
+ acct = ic->acc;
+
+ fb_data_add_thread_head(fata, tid);
+ imcb_log(ic, "Created chat thread %" FB_ID_FORMAT, tid);
+ imcb_log(ic, "Join: fbjoin %s %d <channel-name>", acct->tag, 1);
+}
+
+static void
+fb_cb_api_threads(FbApi *api, GSList *thrds, gpointer data)
+{
+ FbApiThread *thrd;
+ FbApiUser *user;
+ FbData *fata = data;
+ GSList *phrds = NULL;
+ GSList *l;
+ GSList *m;
+ GString *lines;
+ guint i;
+ guint j;
+ struct im_connection *ic;
+
+ ic = fb_data_get_connection(fata);
+ fb_data_clear_threads(fata);
for (l = thrds, i = 0; (l != NULL) && (i < 25); l = l->next, i++) {
thrd = l->data;
- if (g_slist_length(thrd->users) >= 2)
+ if (g_slist_length(thrd->users) >= 2) {
phrds = g_slist_prepend(phrds, thrd);
+ }
}
if (phrds == NULL) {
- imcb_log(fata->ic, "No chats to display.");
+ imcb_log(ic, "No chats to display.");
return;
}
- ln = g_string_new(NULL);
- imcb_log(fata->ic, "%2s %-20s %s", "ID", "Topic", "Participants");
+ lines = g_string_new(NULL);
+ imcb_log(ic, "%2s %-20s %s", "ID", "Topic", "Participants");
phrds = g_slist_reverse(phrds);
for (l = phrds, i = 1; l != NULL; l = l->next, i++) {
thrd = l->data;
-
- if (g_slist_length(thrd->users) < 2)
- continue;
-
- mptr = g_memdup(&thrd->tid, sizeof thrd->tid);
- fata->tids = g_slist_prepend(fata->tids, mptr);
-
- g_string_printf(ln, "%2d", i);
+ fb_data_add_thread_tail(fata, thrd->tid);
+ g_string_printf(lines, "%2d", i);
if (thrd->topic != NULL) {
if (strlen(thrd->topic) > 20) {
for (j = 16; g_ascii_isspace(thrd->topic[j]) && (j > 0); j--);
- g_string_append_printf(ln, " %-.*s...", ++j, thrd->topic);
- g_string_append_printf(ln, "%*s", 17 - j, "");
+ g_string_append_printf(lines, " %-.*s...", ++j, thrd->topic);
+ g_string_append_printf(lines, "%*s", 17 - j, "");
} else {
- g_string_append_printf(ln, " %-20s", thrd->topic);
+ g_string_append_printf(lines, " %-20s", thrd->topic);
}
} else {
- g_string_append_printf(ln, " %20s", "");
+ g_string_append_printf(lines, " %20s", "");
}
for (m = thrd->users, j = 0; (m != NULL) && (j < 3); m = m->next, j++) {
user = m->data;
- g_string_append(ln, (j != 0) ? ", " : " ");
- g_string_append(ln, user->name);
+ g_string_append(lines, (j != 0) ? ", " : " ");
+ g_string_append(lines, user->name);
}
- if (m != NULL)
- g_string_append(ln, "...");
+ if (m != NULL) {
+ g_string_append(lines, "...");
+ }
- imcb_log(fata->ic, "%s", ln->str);
+ imcb_log(ic, "%s", lines->str);
}
- fata->tids = g_slist_reverse(fata->tids);
- g_string_free(ln, TRUE);
+ g_string_free(lines, TRUE);
g_slist_free(phrds);
}
-/**
- * Implemented #fb_api_funcs->typing().
- *
- * @param api The #fb_api.
- * @param typg The #fb_api_typing.
- * @param data The user defined data, which is #fb_data.
- **/
-static void fb_cb_api_typing(fb_api_t *api, fb_api_typing_t *typg,
- gpointer data)
+static void
+fb_cb_api_typing(FbApi *api, FbApiTyping *typg, gpointer data)
{
- fb_data_t *fata = data;
- guint32 flags;
- gchar uid[FB_ID_STRMAX];
+ FbData *fata = data;
+ gchar uid[FB_ID_STRMAX];
+ guint32 flags;
+ struct im_connection *ic;
FB_ID_TO_STR(typg->uid, uid);
+ ic = fb_data_get_connection(fata);
flags = typg->state ? OPT_TYPING : 0;
- imcb_buddy_typing(fata->ic, uid, flags);
+ imcb_buddy_typing(ic, uid, flags);
}
-/**
- * Creates a new #fb_data with an #account. The returned #fb_data
- * should be freed with #fb_data_free() when no longer needed.
- *
- * @param acc The #account.
- *
- * @return The #fb_data or NULL on error.
- **/
-fb_data_t *fb_data_new(account_t *acc)
-{
- fb_data_t *fata;
- gchar *uid;
-
- static const fb_api_funcs_t funcs = {
- .error = fb_cb_api_error,
- .auth = fb_cb_api_auth,
- .connect = fb_cb_api_connect,
- .contacts = fb_cb_api_contacts,
- .message = fb_cb_api_message,
- .presence = fb_cb_api_presence,
- .thread_create = fb_cb_api_thread_create,
- .thread_info = fb_cb_api_thread_info,
- .thread_list = fb_cb_api_thread_list,
- .typing = fb_cb_api_typing
- };
-
- g_return_val_if_fail(acc != NULL, NULL);
-
- fata = g_new0(fb_data_t, 1);
- fata->api = fb_api_new(&funcs, fata);
-
- fata->ic = imcb_new(acc);
- fata->ic->proto_data = fata;
-
- uid = set_getstr(&acc->set, "uid");
-
- if (uid != NULL)
- fata->api->uid = FB_ID_FROM_STR(uid);
-
- fata->api->token = g_strdup(set_getstr(&acc->set, "token"));
- fata->api->stoken = g_strdup(set_getstr(&acc->set, "stoken"));
- fata->api->cid = g_strdup(set_getstr(&acc->set, "cid"));
- fata->api->mid = g_strdup(set_getstr(&acc->set, "mid"));
- fata->api->cuid = g_strdup(set_getstr(&acc->set, "cuid"));
-
- fb_api_rehash(fata->api);
-
- set_setstr(&acc->set, "cid", fata->api->cid);
- set_setstr(&acc->set, "mid", fata->api->mid);
- set_setstr(&acc->set, "cuid", fata->api->cuid);
-
- return fata;
-}
-
-/**
- * Frees all memory used by a #fb_data.
- *
- * @param sata The #fb_data.
- **/
-void fb_data_free(fb_data_t *fata)
-{
- if (G_UNLIKELY(fata == NULL))
- return;
-
- fb_api_free(fata->api);
- g_slist_free_full(fata->tids, g_free);
- g_slist_free_full(fata->gcs, (GDestroyNotify) imcb_chat_free);
- g_free(fata);
-}
-
-/**
- * Creates a new #groupchat and adds it to the #fb_data. The returned
- * #groupchat should be freed with #fb_data_groupchat_free() when no
- * longer needed.
- *
- * @param ic The #im_connection.
- * @param tid The thread #fb_id.
- * @param name The name of the channel.
- *
- * @return The #groupchat or NULL on error.
- **/
-struct groupchat *fb_data_groupchat_new(struct im_connection *ic,
- fb_id_t tid,
- const gchar *name)
+static struct groupchat *
+fb_data_groupchat_new(struct im_connection *ic, FbId tid, const gchar *name)
{
- fb_data_t *fata = ic->proto_data;
+ FbApi *api;
+ FbData *fata = ic->proto_data;
+ gchar stid[FB_ID_STRMAX];
+ irc_channel_t *ch;
struct groupchat *gc;
- irc_channel_t *ch;
- gchar stid[FB_ID_STRMAX];
FB_ID_TO_STR(tid, stid);
- if (bee_chat_by_title(ic->bee, ic, stid) != NULL)
+ if (bee_chat_by_title(ic->bee, ic, stid) != NULL) {
return NULL;
+ }
if (name != NULL) {
- if (strchr(CTYPES, name[0]) != NULL)
+ if (strchr(CTYPES, name[0]) != NULL) {
name++;
+ }
/* Let the hackery being... */
gc = imcb_chat_new(ic, stid);
@@ -445,385 +526,257 @@ struct groupchat *fb_data_groupchat_new(struct im_connection *ic,
}
gc = imcb_chat_new(ic, stid);
- ch = gc->ui_data;
- fata->gcs = g_slist_prepend(fata->gcs, gc);
+ fb_data_add_groupchat(fata, gc);
+ ch = gc->ui_data;
ch->flags &= ~IRC_CHANNEL_CHAT_PICKME;
- imcb_chat_add_buddy(gc, ic->acc->user);
- fb_api_thread_info(fata->api, tid);
+ api = fb_data_get_api(fata);
+ imcb_chat_add_buddy(gc, ic->acc->user);
+ fb_api_thread(api, tid);
return gc;
}
-/**
- * Frees all memory used by a #groupchat and removes it from the
- * #fb_data.
- *
- * @param gc The #groupchat.
- **/
-void fb_data_groupchat_free(struct groupchat *gc)
-{
- fb_data_t *fata;
-
- if (G_UNLIKELY(gc == NULL))
- return;
-
- if (G_LIKELY(gc->ic != NULL)) {
- fata = gc->ic->proto_data;
- fata->gcs = g_slist_remove(fata->gcs, gc);
- }
-
- imcb_chat_free(gc);
-}
-
-/**
- * Implements #prpl->init(). This initializes an account.
- *
- * @param acc The #account.
- **/
-static void fb_init(account_t *acc)
+static void
+fb_init(account_t *acct)
{
set_t *s;
- s = set_add(&acc->set, "cid", NULL, NULL, acc);
+ s = set_add(&acct->set, "cid", NULL, NULL, acct);
s->flags = SET_NULL_OK | SET_HIDDEN;
- s = set_add(&acc->set, "cuid", NULL, NULL, acc);
+ s = set_add(&acct->set, "did", NULL, NULL, acct);
s->flags = SET_NULL_OK | SET_HIDDEN;
- s = set_add(&acc->set, "mid", NULL, NULL, acc);
+ s = set_add(&acct->set, "mid", NULL, NULL, acct);
s->flags = SET_NULL_OK | SET_HIDDEN;
- s = set_add(&acc->set, "token", NULL, NULL, acc);
+ s = set_add(&acct->set, "token", NULL, NULL, acct);
s->flags = SET_NULL_OK | SET_HIDDEN | SET_PASSWORD;
- s = set_add(&acc->set, "stoken", NULL, NULL, acc);
+ s = set_add(&acct->set, "stoken", NULL, NULL, acct);
s->flags = SET_NULL_OK | SET_HIDDEN;
- s = set_add(&acc->set, "uid", NULL, NULL, acc);
+ s = set_add(&acct->set, "uid", NULL, NULL, acct);
s->flags = SET_NULL_OK | SET_HIDDEN;
+
+ set_add(&acct->set, "mark_read", "true", set_eval_bool, acct);
+ set_add(&acct->set, "show_unread", "true", set_eval_bool, acct);
+ set_add(&acct->set, "sync_interval", "30", set_eval_int, acct);
}
-/**
- * Implements #prpl->login(). This logins an account in.
- *
- * @param acc The #account.
- **/
-static void fb_login(account_t *acc)
+static void
+fb_login(account_t *acc)
{
- fb_data_t *fata;
+ FbApi *api;
+ FbData *fata;
+ struct im_connection *ic;
fata = fb_data_new(acc);
- imcb_log(fata->ic, "Connecting");
-
- if (fata->api->token == NULL) {
- imcb_log(fata->ic, "Requesting authentication token");
- fb_api_auth(fata->api, acc->user, acc->pass);
+ api = fb_data_get_api(fata);
+ ic = fb_data_get_connection(fata);
+ ic->proto_data = fata;
+
+ g_signal_connect(api,
+ "auth",
+ G_CALLBACK(fb_cb_api_auth),
+ fata);
+ g_signal_connect(api,
+ "connect",
+ G_CALLBACK(fb_cb_api_connect),
+ fata);
+ g_signal_connect(api,
+ "contact",
+ G_CALLBACK(fb_cb_api_contact),
+ fata);
+ g_signal_connect(api,
+ "contacts",
+ G_CALLBACK(fb_cb_api_contacts),
+ fata);
+ g_signal_connect(api,
+ "error",
+ G_CALLBACK(fb_cb_api_error),
+ fata);
+ g_signal_connect(api,
+ "events",
+ G_CALLBACK(fb_cb_api_events),
+ fata);
+ g_signal_connect(api,
+ "messages",
+ G_CALLBACK(fb_cb_api_messages),
+ fata);
+ g_signal_connect(api,
+ "presences",
+ G_CALLBACK(fb_cb_api_presences),
+ fata);
+ g_signal_connect(api,
+ "thread",
+ G_CALLBACK(fb_cb_api_thread),
+ fata);
+ g_signal_connect(api,
+ "thread-create",
+ G_CALLBACK(fb_cb_api_thread_create),
+ fata);
+ g_signal_connect(api,
+ "threads",
+ G_CALLBACK(fb_cb_api_threads),
+ fata);
+ g_signal_connect(api,
+ "typing",
+ G_CALLBACK(fb_cb_api_typing),
+ fata);
+
+ if (!fb_data_load(fata)) {
+ imcb_log(ic, "Authenticating");
+ fb_api_auth(api, acc->user, acc->pass);
return;
}
- imcb_log(fata->ic, "Fetching contacts");
- fb_api_contacts(fata->api);
+ imcb_log(ic, "Fetching contacts");
+ fb_api_contacts(api);
}
-/**
- * Implements #prpl->logout(). This logs an account out.
- *
- * @param ic The #im_connection.
- **/
-static void fb_logout(struct im_connection *ic)
+static void
+fb_logout(struct im_connection *ic)
{
- fb_data_t *fata = ic->proto_data;
+ FbApi *api;
+ FbData *fata = ic->proto_data;
- if (fata->api->stoken == NULL) {
- set_reset(&ic->acc->set, "stoken");
- }
+ api = fb_data_get_api(fata);
+ ic->proto_data = NULL;
- fb_api_disconnect(fata->api);
- fb_data_free(fata);
+ fb_data_save(fata);
+ fb_api_disconnect(api);
+ g_object_unref(fata);
}
-/**
- * Implements #prpl->buddy_msg(). This sends a message to a buddy.
- *
- * @param ic The #im_connection.
- * @param to The handle of the buddy.
- * @param message The message to send.
- * @param flags The message flags. (Irrelevant to this plugin)
- *
- * @return 0. (Upstream bitlbee does nothing with this)
- **/
-static int fb_buddy_msg(struct im_connection *ic, char *to, char *message,
- int flags)
+static int
+fb_buddy_msg(struct im_connection *ic, char *to, char *message, int flags)
{
- fb_data_t *fata = ic->proto_data;
- fb_id_t uid;
+ FbApi *api;
+ FbData *fata = ic->proto_data;
+ FbId uid;
+ api = fb_data_get_api(fata);
uid = FB_ID_FROM_STR(to);
- fb_api_message(fata->api, uid, FALSE, message);
+ fb_api_message(api, uid, FALSE, message);
return 0;
}
-/**
- * Implements #prpl->send_typing(). This sends the typing state message.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- * @param flags The message flags. (Irrelevant to this plugin)
- *
- * @return 0. (Upstream bitlbe does nothing with this)
- **/
-static int fb_send_typing(struct im_connection *ic, char *who, int flags)
+static int
+fb_send_typing(struct im_connection *ic, char *who, int flags)
{
- fb_data_t *fata = ic->proto_data;
- fb_id_t uid;
- gboolean state;
+ FbApi *api;
+ FbData *fata = ic->proto_data;
+ FbId uid;
+ gboolean state;
- uid = FB_ID_FROM_STR(who);
+ api = fb_data_get_api(fata);
+ uid = FB_ID_FROM_STR(who);
state = (flags & OPT_TYPING) != 0;
- fb_api_typing(fata->api, uid, state);
+ fb_api_typing(api, uid, state);
return 0;
}
-/**
- * Implements #prpl->add_buddy(). This adds a buddy.
- *
- * @param ic The #im_connection.
- * @param name The name of the buddy to add.
- * @param group The group of the buddy. (Irrelevant to this plugin)
- **/
-static void fb_add_buddy(struct im_connection *ic, char *name, char *group)
+static void
+fb_add_buddy(struct im_connection *ic, char *name, char *group)
{
}
-/**
- * Implements #prpl->remove_buddy(). This removes a buddy.
- *
- * @param ic The #im_connection.
- * @param name The name of the buddy to add.
- * @param group The group of the buddy. (Irrelevant to this plugin)
- **/
-static void fb_remove_buddy(struct im_connection *ic, char *name, char *group)
+static void
+fb_remove_buddy(struct im_connection *ic, char *name, char *group)
{
}
-/**
- * Implements #prpl->add_permit(). This is not used by the plugin.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_add_permit(struct im_connection *ic, char *who)
+static void
+fb_chat_invite(struct groupchat *gc, char *who, char *message)
{
+ FbApi *api;
+ FbData *fata = gc->ic->proto_data;
+ FbId tid;
+ FbId uid;
-}
-
-/**
- * Implements #prpl->add_deny(). This blocks a buddy.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_add_deny(struct im_connection *ic, char *who)
-{
-
-}
-
-/**
- * Implements #prpl->rem_permit(). This is not used by the plugin.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_rem_permit(struct im_connection *ic, char *who)
-{
-
-}
-
-/**
- * Implements #prpl->rem_deny(). This unblocks a buddy.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_rem_deny(struct im_connection *ic, char *who)
-{
-
-}
-
-/**
- * Implements #prpl->get_info(). This retrieves the info of a buddy.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_get_info(struct im_connection *ic, char *who)
-{
-
-}
-
-/**
- * Implements #prpl->chat_invite(). This invites a user to a #groupchat.
- *
- * @param gc The #groupchat.
- * @param who Ignored.
- * @param message The handle to invite.
- **/
-void fb_chat_invite(struct groupchat *gc, char *who, char *message)
-{
- fb_data_t *fata = gc->ic->proto_data;
- fb_id_t tid;
- fb_id_t uid;
-
+ api = fb_data_get_api(fata);
tid = FB_ID_FROM_STR(gc->title);
uid = FB_ID_FROM_STR(who);
- fb_api_thread_invite(fata->api, tid, uid);
+
+ fb_api_thread_invite(api, tid, uid);
imcb_chat_add_buddy(gc, who);
}
-/**
- * Implements #prpl->chat_leave(). This leaves a #groupchat.
- *
- * @param gc The #groupchat.
- **/
-void fb_chat_leave(struct groupchat *gc)
+static void
+fb_chat_leave(struct groupchat *gc)
{
- fb_data_groupchat_free(gc);
+ FbData *fata = gc->ic->proto_data;
+
+ fb_data_remove_groupchat(fata, gc);
+ imcb_chat_free(gc);
}
-/**
- * Implements #prpl->chat_msg(). This sends a message to a #groupchat.
- *
- * @param gc The #groupchat.
- * @param message The message to send.
- * @param flags Ignored.
- **/
-void fb_chat_msg(struct groupchat *gc, char *message, int flags)
+static void
+fb_chat_msg(struct groupchat *gc, char *message, int flags)
{
- fb_data_t *fata = gc->ic->proto_data;
- fb_id_t tid;
+ FbApi *api;
+ FbData *fata = gc->ic->proto_data;
+ FbId tid;
+ api = fb_data_get_api(fata);
tid = FB_ID_FROM_STR(gc->title);
- fb_api_message(fata->api, tid, TRUE, message);
+ fb_api_message(api, tid, TRUE, message);
}
-/**
- * Implements #prpl->chat_join(). This joins a #groupchat.
- *
- * @param ic The #im_connection.
- * @param room The room name.
- * @param nick The nick name.
- * @param password The password.
- * @param sets The #set array.
- **/
-struct groupchat *fb_chat_join(struct im_connection *ic, const char *room,
- const char *nick, const char *password,
- set_t **sets)
+static struct groupchat *
+fb_chat_join(struct im_connection *ic, const char *room, const char *nick,
+ const char *password, set_t **sets)
{
- fb_data_t *fata = ic->proto_data;
- fb_id_t tid;
+ FbId tid;
struct groupchat *gc;
tid = FB_ID_FROM_STR(room);
- gc = fb_data_groupchat_new(ic, tid, NULL);
+ gc = fb_data_groupchat_new(ic, tid, NULL);
if (gc == NULL) {
- imcb_error(fata->ic, "Failed to join chat: %" FB_ID_FORMAT, tid);
+ imcb_error(ic, "Failed to join chat: %" FB_ID_FORMAT, tid);
return NULL;
}
return gc;
}
-/**
- * Implements #prpl->chat_topic(). This sets a #groupchat topic.
- *
- * @param gc The #groupchat.
- * @param topic The topic
- **/
-void fb_chat_topic(struct groupchat *gc, char *topic)
+static void
+fb_chat_topic(struct groupchat *gc, char *topic)
{
- fb_data_t *fata = gc->ic->proto_data;
- fb_id_t tid;
+ FbApi *api;
+ FbData *fata = gc->ic->proto_data;
+ FbId tid;
+ api = fb_data_get_api(fata);
tid = FB_ID_FROM_STR(gc->title);
- fb_api_thread_topic(fata->api, tid, topic);
+ fb_api_thread_topic(api, tid, topic);
imcb_chat_topic(gc, NULL, topic, 0);
}
-/**
- * Implements #prpl->auth_allow(). This accepts buddy requests.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_auth_allow(struct im_connection *ic, const char *who)
-{
-
-}
-
-/**
- * Implements #prpl->auth_allow(). This denies buddy requests.
- *
- * @param ic The #im_connection.
- * @param who The handle of the buddy.
- **/
-static void fb_auth_deny(struct im_connection *ic, const char *who)
-{
-
-}
-
-/**
- * Implements #prpl->buddy_data_add(). This adds data to the buddy.
- *
- * @param bu The #bee_user.
- **/
-static void fb_buddy_data_add(struct bee_user *bu)
-{
-
-}
-
-/**
- * Implements #prpl->buddy_data_free(). This frees the buddy data.
- *
- * @param bu The #bee_user.
- **/
-static void fb_buddy_data_free(struct bee_user *bu)
-{
-
-}
-
-/**
- * Obtains a #account from command arguments.
- *
- * @param irc The #irc.
- * @param args The command arguments.
- * @param required The amount of required arguments.
- * @param offset The return location for the args offset.
- *
- * @return The #account or NULL on error.
- **/
-static account_t *fb_cmd_account(irc_t *irc, char **args, guint required,
- guint *offset)
+static account_t *
+fb_cmd_account(irc_t *irc, char **args, guint required, guint *offset)
{
account_t *a;
- account_t *acc;
- guint accs;
- guint size;
- guint oset;
+ account_t *acct;
+ guint acctc;
+ guint size;
+ guint oset;
- for (accs = 0, a = irc->b->accounts; a != NULL; a = a->next) {
+ for (acctc= 0, a = irc->b->accounts; a != NULL; a = a->next) {
if ((g_ascii_strcasecmp(a->prpl->name, "facebook") == 0) &&
(a->ic != NULL))
{
- acc = a;
- accs++;
+ acct = a;
+ acctc++;
}
}
- if (accs == 0) {
+ if (acctc == 0) {
irc_rootmsg(irc, "There are no active Facebook accounts!");
return NULL;
}
@@ -831,33 +784,33 @@ static account_t *fb_cmd_account(irc_t *irc, char **args, guint required,
/* Calculate the size of args */
for (size = 1; args[size] != NULL; size++);
- if (accs > 1) {
+ if (acctc > 1) {
if (args[1] == NULL) {
irc_rootmsg(irc, "More than one Facebook account, specify one.");
return NULL;
}
/* More than one account, look up by handle */
- acc = account_get(irc->b, args[1]);
+ acct = account_get(irc->b, args[1]);
oset = 2;
- if (acc == NULL) {
+ if (acct == NULL) {
irc_rootmsg(irc, "Unknown account: %s", args[1]);
return NULL;
}
- if (acc->ic == NULL) {
- irc_rootmsg(irc, "Account not online: %s", acc->tag);
+ if (acct->ic == NULL) {
+ irc_rootmsg(irc, "Account not online: %s", acct->tag);
return NULL;
}
- if (g_ascii_strcasecmp(acc->prpl->name, "facebook") != 0) {
- irc_rootmsg(irc, "Unknown Facebook account: %s", acc->tag);
+ if (g_ascii_strcasecmp(acct->prpl->name, "facebook") != 0) {
+ irc_rootmsg(irc, "Unknown Facebook account: %s", acct->tag);
return NULL;
}
} else if ((size != (required + 1)) &&
(args[1] != NULL) &&
- (account_get(irc->b, args[1]) == acc))
+ (account_get(irc->b, args[1]) == acct))
{
/* One account with an identifier */
oset = 2;
@@ -871,149 +824,138 @@ static account_t *fb_cmd_account(irc_t *irc, char **args, guint required,
return NULL;
}
- if (offset != NULL)
+ if (offset != NULL) {
*offset = oset;
+ }
- return acc;
+ return acct;
}
-/**
- * Implemented #root_command_add() callback for the 'fbchats' command.
- *
- * @param irc The #irc.
- * @param args The command arguments.
- **/
-static void fb_cmd_fbchats(irc_t *irc, char **args)
+static void
+fb_cmd_fbchats(irc_t *irc, char **args)
{
- account_t *acc;
- fb_data_t *fata;
+ account_t *acct;
+ FbApi *api;
+ FbData *fata;
- acc = fb_cmd_account(irc, args, 0, NULL);
+ acct = fb_cmd_account(irc, args, 0, NULL);
- if (acc == NULL)
+ if (acct == NULL) {
return;
+ }
- fata = acc->ic->proto_data;
- fb_api_thread_list(fata->api, 25);
+ fata = acct->ic->proto_data;
+ api = fb_data_get_api(fata);
+ fb_api_threads(api);
}
-/**
- * Implemented #root_command_add() callback for the 'fbcreate' command.
- *
- * @param irc The #irc.
- * @param args The command arguments.
- **/
-static void fb_cmd_fbcreate(irc_t *irc, char **args)
+static void
+fb_cmd_fbcreate(irc_t *irc, char **args)
{
- account_t *acc;
- fb_data_t *fata;
- fb_id_t uid;
+ account_t *acct;
+ FbApi *api;
+ FbData *fata;
+ FbId *duid;
+ FbId uid;
irc_user_t *iu;
- GSList *uids;
- guint oset;
- guint i;
+ GSList *uids = NULL;
+ guint oset;
+ guint i;
+ struct im_connection *ic;
- acc = fb_cmd_account(irc, args, 2, &oset);
- uids = NULL;
+ acct = fb_cmd_account(irc, args, 2, &oset);
- if (acc == NULL)
+ if (acct == NULL) {
return;
+ }
- fata = acc->ic->proto_data;
+ fata = acct->ic->proto_data;
+ ic = fb_data_get_connection(fata);
for (i = oset; args[i] != NULL; i++) {
iu = irc_user_by_name(irc, args[i]);
if (iu != NULL) {
uid = FB_ID_FROM_STR(iu->bu->handle);
- uids = g_slist_prepend(uids, g_memdup(&uid, sizeof uid));
+ duid = g_memdup(&uid, sizeof uid);
+ uids = g_slist_prepend(uids, duid);
}
}
if (uids == NULL) {
- imcb_error(fata->ic, "No valid users specified");
+ imcb_error(ic, "No valid users specified");
return;
}
- fb_api_thread_create(fata->api, uids);
+ api = fb_data_get_api(fata);
+ fb_api_thread_create(api, uids);
g_slist_free_full(uids, g_free);
}
-/**
- * Implemented #root_command_add() callback for the 'fbjoin' command.
- *
- * @param irc The #irc.
- * @param args The command arguments.
- **/
-static void fb_cmd_fbjoin(irc_t *irc, char **args)
+static void
+fb_cmd_fbjoin(irc_t *irc, char **args)
{
- account_t *acc;
- fb_data_t *fata;
- fb_id_t *tid;
- gchar *name;
- guint oset;
- gint64 indx;
+ account_t *acct;
+ FbData *fata;
+ FbId tid;
+ gchar *name;
+ guint i;
+ guint oset;
+ struct im_connection *ic;
- acc = fb_cmd_account(irc, args, 2, &oset);
+ acct = fb_cmd_account(irc, args, 2, &oset);
- if (acc == NULL)
+ if (acct == NULL) {
return;
+ }
+
+ fata = acct->ic->proto_data;
+ ic = fb_data_get_connection(fata);
- fata = acc->ic->proto_data;
name = args[oset + 1];
- indx = g_ascii_strtoll(args[oset], NULL, 10);
- tid = g_slist_nth_data(fata->tids, indx - 1);
+ i = g_ascii_strtoll(args[oset], NULL, 10);
+ tid = fb_data_get_thread(fata, i - 1);
- if ((indx < 1) || (tid == NULL)) {
- imcb_error(fata->ic, "Invalid index: %" G_GINT64_FORMAT, indx);
+ if ((i < 1) || (tid == 0)) {
+ imcb_error(ic, "Invalid index: %u", i);
return;
}
- if (fb_data_groupchat_new(acc->ic, *tid, name) == NULL) {
- imcb_error(fata->ic, "Failed to join chat: %s (%" FB_ID_FORMAT ")",
- name, *tid);
+ if (fb_data_groupchat_new(ic, tid, name) == NULL) {
+ imcb_error(ic, "Failed to join chat: %s (%" FB_ID_FORMAT ")",
+ name, tid);
}
}
-/**
- * Implements the #init_plugin() function. BitlBee looks for this
- * function and executes it to register the protocol and its related
- * callbacks.
- **/
-void init_plugin()
-{
- struct prpl *pp;
-
- pp = g_new0(struct prpl, 1);
-
- pp->name = "facebook";
- pp->options = OPT_NOOTR;
- pp->init = fb_init;
- pp->login = fb_login;
- pp->logout = fb_logout;
- pp->buddy_msg = fb_buddy_msg;
- pp->send_typing = fb_send_typing;
- pp->add_buddy = fb_add_buddy;
- pp->remove_buddy = fb_remove_buddy;
- pp->add_permit = fb_add_permit;
- pp->add_deny = fb_add_deny;
- pp->rem_permit = fb_rem_permit;
- pp->rem_deny = fb_rem_deny;
- pp->get_info = fb_get_info;
- pp->chat_invite = fb_chat_invite;
- pp->chat_leave = fb_chat_leave;
- pp->chat_msg = fb_chat_msg;
- pp->chat_join = fb_chat_join;
- pp->chat_topic = fb_chat_topic;
- pp->handle_cmp = g_ascii_strcasecmp;
- pp->auth_allow = fb_auth_allow;
- pp->auth_deny = fb_auth_deny;
- pp->buddy_data_add = fb_buddy_data_add;
- pp->buddy_data_free = fb_buddy_data_free;
-
- register_protocol(pp);
-
- root_command_add("fbchats", 0, fb_cmd_fbchats, 0);
+G_MODULE_EXPORT void
+init_plugin(void);
+
+G_MODULE_EXPORT void
+init_plugin(void)
+{
+ struct prpl *dpp;
+
+ static const struct prpl pp = {
+ .name = "facebook",
+ .init = fb_init,
+ .login = fb_login,
+ .logout = fb_logout,
+ .buddy_msg = fb_buddy_msg,
+ .send_typing = fb_send_typing,
+ .add_buddy = fb_add_buddy,
+ .remove_buddy = fb_remove_buddy,
+ .chat_invite = fb_chat_invite,
+ .chat_leave = fb_chat_leave,
+ .chat_msg = fb_chat_msg,
+ .chat_join = fb_chat_join,
+ .chat_topic = fb_chat_topic,
+ .handle_cmp = g_strcmp0
+ };
+
+ dpp = g_memdup(&pp, sizeof pp);
+ register_protocol(dpp);
+
+ root_command_add("fbchats", 0, fb_cmd_fbchats, 0);
root_command_add("fbcreate", 0, fb_cmd_fbcreate, 0);
- root_command_add("fbjoin", 0, fb_cmd_fbjoin, 0);
+ root_command_add("fbjoin", 0, fb_cmd_fbjoin, 0);
}