--- Makefile | 3 configure | 11 protocols/libmsn/Makefile | 18 protocols/libmsn/libmsn.cxx | 294 +++++++++++ protocols/libmsn/libmsn.h | 44 + protocols/libmsn/msn_callbacks.cxx | 921 +++++++++++++++++++++++++++++++++++++ protocols/libmsn/msn_callbacks.h | 100 ++++ protocols/nogaim.c | 5 8 files changed, 1395 insertions(+), 1 deletion(-) Index: bitlbee-bzr-main-409/Makefile =================================================================== --- bitlbee-bzr-main-409.orig/Makefile +++ bitlbee-bzr-main-409/Makefile @@ -117,7 +117,8 @@ $(objects): Makefile Makefile.settings c $(OUTFILE): $(objects) $(subdirs) @echo '*' Linking $(OUTFILE) - @$(CC) $(objects) $(subdirobjs) -o $(OUTFILE) $(LFLAGS) $(EFLAGS) +#@$(CC) $(objects) $(subdirobjs) -o $(OUTFILE) $(LFLAGS) $(EFLAGS) + g++ $(objects) $(subdirobjs) -o $(OUTFILE) $(LFLAGS) $(EFLAGS) ifndef DEBUG @echo '*' Stripping $(OUTFILE) @-$(STRIP) $(OUTFILE) Index: bitlbee-bzr-main-409/configure =================================================================== --- bitlbee-bzr-main-409.orig/configure +++ bitlbee-bzr-main-409/configure @@ -25,6 +25,7 @@ msn=1 jabber=1 oscar=1 yahoo=1 +libmsn=1 debug=0 strip=1 @@ -65,6 +66,7 @@ Option Description Default --jabber=0/1 Disable/enable Jabber part $jabber --oscar=0/1 Disable/enable Oscar part (ICQ, AIM) $oscar --yahoo=0/1 Disable/enable Yahoo part $yahoo +--libmsn=0/1 Disable/enable libmsn part $libmsn --debug=0/1 Disable/enable debugging $debug --strip=0/1 Disable/enable binary stripping $strip @@ -478,6 +480,15 @@ else protoobjs=$protoobjs'yahoo_mod.o ' fi +if [ "$libmsn" = 0 ]; then + echo '#undef WITH_LIBMSN' >> config.h +else + echo '#define WITH_LIBMSN' >> config.h + protocols=$protocols'libmsn ' + protoobjs=$protoobjs'libmsn_mod.o ' + echo 'EFLAGS+=-lmsn -lssl -lcrypto' >> Makefile.settings +fi + if [ "$protocols" = "PROTOCOLS = " ]; then echo "Warning: You haven't selected any communication protocol to compile!" echo " BitlBee will run, but you will be unable to connect to IM servers!" Index: bitlbee-bzr-main-409/protocols/libmsn/Makefile =================================================================== --- /dev/null +++ bitlbee-bzr-main-409/protocols/libmsn/Makefile @@ -0,0 +1,18 @@ +-include ../../Makefile.settings + +CXX=g++ +CFLAGS += -Wall +LFLAGS += -r + + +default:libmsn_mod.o + +%.o:%.cxx *.h + $(CXX) -c $(CFLAGS) -o $@ $< + +OBJS=libmsn.o msn_callbacks.o +libmsn_mod.o:$(OBJS) + $(LD) $(LFLAGS) $(OBJS) -o $@ + +clean: + rm -f $(OBJS) libmsn_mod.o Index: bitlbee-bzr-main-409/protocols/libmsn/libmsn.cxx =================================================================== --- /dev/null +++ bitlbee-bzr-main-409/protocols/libmsn/libmsn.cxx @@ -0,0 +1,294 @@ +extern "C" { +#include "nogaim.h" + +void libmsn_initmodule(); + +void libmsn_init(account_t *account); +void libmsn_login(account_t *account); +void libmsn_logout(struct im_connection *); +int libmsn_buddy_msg(struct im_connection *, char *to, char *msg, int flags); +void libmsn_set_away(struct im_connection *, char *state, char *msg); +void libmsn_add_buddy(struct im_connection *, char *name, char *group); +void libmsn_remove_buddy(struct im_connection *, char *name, char *group); + +} /* extern "C" */ + + +#include "libmsn.h" + +void libmsn_init(account_t *account) +{ + dbg("\n"); +} + +void libmsn_login(account_t *account) +{ + struct im_connection *ic = imcb_new(account); + struct libmsn_data *md = g_new0(struct libmsn_data, 1); + + dbg("%c",'\n'); + + ic->proto_data = md; + try { + md->uname = new MSN::Passport(account->user); + } catch (MSN::InvalidPassport &e) { + dbg("%s\n", "Invalid passport (account username)"); + imc_logout(ic, FALSE); + return; + } + + md->cb = new Callbacks(ic); + + imcb_log(ic, "Connecting..."); + + md->ic = ic; + md->conn = new MSN::NotificationServerConnection(*md->uname, std::string(account->pass), *md->cb); + md->conn->connect("messenger.hotmail.com", 1863); +} + +void libmsn_logout(struct im_connection *ic) +{ + struct libmsn_data *md = (libmsn_data*)ic->proto_data; + + delete md->uname; + delete md->conn; + delete md->cb; + g_free(md); +} + +int libmsn_buddy_msg(struct im_connection *ic, char *to, char *msg, int flags) +{ + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + dbg("%c",'\n'); + + /* offline? send OIM, and tell the user */ + if (md->cb->onlineu.count(to) == 0 && + md->cb->sb_buddy_chats_r.count(to) == 0) { + MSN::Soap::OIM oim; + oim.myFname = md->cb->myFriendlyName; + oim.toUsername = to; + oim.message = msg; + oim.myUsername = ic->acc->user; + oim.id = 1; // eh? + + imcb_log(ic, "User offline, so we're sending OIM"); + // TODO should tell it in same window, probably (like "User is offline"), how? + md->conn->send_oim(oim); + return 1; + } + + /* already have a switchboard connection for this person? */ + if (md->cb->sb_buddy_chats_r.count(to)) { + md->cb->sb_buddy_chats_r[to]->sendMessage(msg); + } else { + const std::string rcpt_ = to; + const std::string msg_ = msg; + const std::pair *ctx = new std::pair(rcpt_, msg_); + md->conn->requestSwitchboardConnection(ctx); + } + + /* return 1 on ok? */ + return 1; +} + +void libmsn_set_away(struct im_connection *ic, char *state, char *msg) +{ + struct libmsn_data *md = (libmsn_data*)ic->proto_data; + + dbg("%c",'\n'); + + const struct msn_away_state *st; + + if (strcmp(state, GAIM_AWAY_CUSTOM) == 0) + st = msn_away_state_by_name("Away"); + else + st = msn_away_state_by_name(state); + + if (!st) + st = &msn_away_state_list[0]; + + md->conn->setState(MSN::buddyStatusFromString(st->code), 0 /* TODO lowpri */); +} + +void libmsn_add_buddy(struct im_connection *ic, char *name, char *group) +{ + dbg("%c",'\n'); + + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + // XXX address book vs. contact list? AB has a callback, so we can set friendlyname + md->conn->addToAddressBook(name); + //md->conn->addToList(MSN::LST_AB, name); +} + +void libmsn_remove_buddy(struct im_connection *ic, char *name, char *group) +{ + dbg("%c",'\n'); + + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + //md->conn->removeFromList(MSN::LST_AB, name); + md->conn->delFromAddressBook(md->cb->contactids[name], name);; + + // erase this one:? + md->cb->contactids.erase(name); +} + +void libmsn_add_permit(struct im_connection *ic, char *name) +{ + dbg("%c",'\n'); + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + md->conn->addToList(MSN::LST_AL, name); +} + +void libmsn_add_deny(struct im_connection *ic, char *name) +{ + dbg("%c",'\n'); + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + md->conn->addToList(MSN::LST_BL, name); +} + +void libmsn_rem_permit(struct im_connection *ic, char *name) +{ + dbg("%c",'\n'); + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + md->conn->removeFromList(MSN::LST_AL, name); +} + +void libmsn_rem_deny(struct im_connection *ic, char *name) +{ + dbg("%c",'\n'); + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + md->conn->removeFromList(MSN::LST_BL, name); +} + +void libmsn_keepalive(struct im_connection *ic) +{ + dbg("%c",'\n'); + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + md->conn->sendPing(); +} + +GList *libmsn_away_states(struct im_connection *ic) +{ + static GList *l = NULL; + int i; + + if( l == NULL ) + for( i = 0; msn_away_state_list[i].number > -1; i ++ ) + l = g_list_append( l, (void*) msn_away_state_list[i].name ); + + return l; +} + +/* groupchat */ +void libmsn_chat_invite(struct groupchat *gc, char *who, char *message) +{ + struct libmsn_data *md = (libmsn_data *)gc->ic->proto_data; + dbg("%c",'\n'); + + md->cb->sb_chats_r[gc]->inviteUser(who); +} + +void libmsn_chat_leave(struct groupchat *gc) +{ + struct libmsn_data *md = (libmsn_data *)gc->ic->proto_data; + dbg("%c",'\n'); + + md->cb->sb_chats.erase(md->cb->sb_chats_r[gc]); + md->cb->sb_chats_r.erase(gc); + + // sb connection times out itself or what? +} + +void libmsn_chat_msg(struct groupchat *gc, char *message, int flags) +{ + struct im_connection *ic = (im_connection *)gc->ic; + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + + dbg("%c",'\n'); + + md->cb->sb_chats_r[gc]->sendMessage(message); + +} + +struct groupchat * libmsn_chat_with(struct im_connection *ic, char *to) +{ + struct libmsn_data *md = (libmsn_data *)ic->proto_data; + struct groupchat *gc; + dbg("%c",'\n'); + + /* too simple? */ + gc = imcb_chat_new(ic, "blah, some text"); + imcb_chat_add_buddy(gc, to); + imcb_chat_add_buddy(gc, md->uname->c_str()); + + /* already have a switchboard connection for this person? convert to groupchat*/ + // cb->chatToGC? + if (md->cb->sb_buddy_chats_r.count(to)) { + MSN::SwitchboardServerConnection *sb = md->cb->sb_buddy_chats_r[to]; + md->cb->sb_chats[sb] = gc; + md->cb->sb_chats_r[gc] = sb; + md->cb->sb_buddy_chats.erase(sb); + md->cb->sb_buddy_chats_r.erase(to); + } else { + // create new sb + // now, this is an ugly hack, prepend a space to passport to let callback know it's a groupchat + const std::string rcpt_ = to; + const std::pair *ctx = new std::pair(std::string(" ")+to, gc); + md->conn->requestSwitchboardConnection(ctx); + } + // must create sb conn if not already + + return gc; +} + +/*struct groupchat * libmsn_chat_join(struct groupchat *, char *who, char *message) +{ dbg("%c",'\n'); }*/ + +void libmsn_chat_topic(struct groupchat *, char *topic) +{ + dbg("%c",'\n'); +} + + +void libmsn_initmodule() +{ + struct prpl *prpl = g_new0(struct prpl, 1); + + dbg("%c",'\n'); + + prpl->name = "libmsn"; +#define FOO(x) prpl->x = libmsn_ ## x + FOO(init); + FOO(login); + FOO(logout); + FOO(buddy_msg); + FOO(set_away); + FOO(add_buddy); + FOO(remove_buddy); + + FOO(chat_invite); + FOO(chat_leave); + FOO(chat_msg); + FOO(chat_with); +// FOO(chat_join); + FOO(chat_topic); + + FOO(keepalive); + FOO(add_permit); + FOO(add_deny); + FOO(rem_permit); + FOO(rem_deny); + + FOO(away_states); + prpl->handle_cmp = g_strcasecmp; + + register_protocol(prpl); +} Index: bitlbee-bzr-main-409/protocols/libmsn/libmsn.h =================================================================== --- /dev/null +++ bitlbee-bzr-main-409/protocols/libmsn/libmsn.h @@ -0,0 +1,44 @@ +#ifndef LIBMSN_H +#define LIBMSN_H + +#include +#include "msn_callbacks.h" + + +extern "C" { +struct libmsn_data { + struct im_connection *ic; + + MSN::NotificationServerConnection *conn; + MSN::Passport *uname; + Callbacks *cb; +}; + +// for tables.c stuff +#include "nogaim.h" +#include "msn/msn.h" +extern const struct msn_away_state msn_away_state_list[]; +extern const struct msn_status_code msn_status_code_list[]; + +const struct msn_away_state *msn_away_state_by_number( int number ); +const struct msn_away_state *msn_away_state_by_code( char *code ); +const struct msn_away_state *msn_away_state_by_name( char *name ); +const struct msn_status_code *msn_status_by_number( int number ); + + +/* there's probably a better way to debug. like a fake irc user, channel? */ +//#define DEBUG +#ifdef DEBUG +#include +#define dbg(x...) \ + do { \ + fprintf(stderr, " %s:%i ", __func__, __LINE__); \ + fprintf(stderr, x); \ + } while (0) + +#else +#define dbg(x...) +#endif + +} /* extern "C" */ +#endif Index: bitlbee-bzr-main-409/protocols/libmsn/msn_callbacks.cxx =================================================================== --- /dev/null +++ bitlbee-bzr-main-409/protocols/libmsn/msn_callbacks.cxx @@ -0,0 +1,921 @@ +/* + * based on: + * msntest.cpp + * libmsn + * + * Created by Meredydd Luff. + * Refactored by Tiago Salem Herrmann + * Copyright (c) 2004 Meredydd Luff. All rights reserved. + * Copyright (c) 2007 Tiago Salem Herrmann. All rights reserved. + * + * 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 + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "libmsn.h" +#include "msn_callbacks.h" + +extern "C" { +#include "nogaim.h" +} + +#ifdef DEBUG_SOCKETS +#define dbgs dbg +#else +#define dbgs(args...) +#endif + +#ifndef DEBUG +#define printf(x...) +#endif + +Callbacks::Callbacks(struct im_connection *ic) +{ + dbg("%c", '\n'); + this->ic = ic; + + // should be random, HAH, copying bad code doesn't make it better ;-) + sessionID = 123456; +} + +Callbacks::~Callbacks() +{ + dbg("%c", '\n'); +} + +extern "C" gboolean libmsn_cb(gpointer data, gint source, b_input_condition cond) +{ + struct im_connection *ic = (im_connection*)data; + struct libmsn_data *md = (libmsn_data*)ic->proto_data; + MSN::Connection *c = md->conn->connectionWithSocket(source); + + if (c == NULL) { + dbg("wot, no connection on this fd?%c", '\n'); + return FALSE; + } + + if (c->isConnected() == false) { + dbgs("COMPL%c", '\n'); + c->socketConnectionCompleted(); + } + + if (cond & GAIM_INPUT_READ) { + dbgs("READ%c", '\n'); + c->dataArrivedOnSocket(); + } + if (cond & GAIM_INPUT_WRITE) { +// dbgs("WRITE%c", '\n'); + c->socketIsWritable(); + } + + return TRUE; // false on err +} + +void Callbacks::registerSocket(int fd, int reading, int writing) +{ + dbgs("%i -------------------------------- ; %s,%s%c", fd, reading?"reading":"", writing?"writing":"",'\n'); + + if (fd < 1) { + dbg("%s; fd==%i\n", "YOU SUCK!!!", fd); + return; + } + if (writing) { + sockets.insert(std::pair(fd, b_input_add(fd, GAIM_INPUT_WRITE, libmsn_cb, ic))); + } + if (reading) { + sockets.insert(std::pair(fd, b_input_add(fd, GAIM_INPUT_READ, libmsn_cb, ic))); + } +// ic->inpa = b_input_add(fd, GAIM_INPUT_READ, libmsn_cb, ic); +} + +void Callbacks::closeSocket(int fd) +{ + dbgs("%i -------------------------------- %c", fd, '\n'); + closesocket(fd); + //close(fd); +} + +void Callbacks::unregisterSocket(int fd) +{ + dbgs("%i -------------------------------- %c", fd, '\n'); + + std::multimap::iterator it = sockets.find(fd);; + for (; it != sockets.end(); it++) + b_event_remove(it->second); + + sockets.erase(fd); +// ic->inpa = 0; +} + +void Callbacks::gotFriendlyName(MSN::NotificationServerConnection * conn, std::string friendlyname) +{ + dbg("%c", '\n'); + myFriendlyName = friendlyname.c_str(); + printf("Your friendlyname is now: %s\n", friendlyname.c_str()); +} + +void Callbacks::gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * info) +{ + dbg("%c", '\n'); + // IMPORTANT + // Here you need to fill a vector with all your contacts + // both received by the server and previous ones. + // Next pass this vector to the function completeConnection() + // if you dont call completeConnection(), the service will + // not work. + std::map::iterator i = info->contactList.begin(); + std::map allContacts; + + for (; i != info->contactList.end(); i++) + { + MSN::Buddy *contact = (*i).second; + const char *user = contact->userName.c_str(); + + if(contact->lists & MSN::LST_AB ) // only if it is the address book + { + /* groups ignored for now, bitlbee doesn't implement them anyways */ + imcb_add_buddy(ic, user, NULL); + imcb_rename_buddy(ic, user, contact->friendlyName.c_str()); + contactids[user] = contact->properties["contactId"]; + + + allContacts[contact->userName.c_str()]=0; + allContacts[contact->userName.c_str()]+=1; + printf("-AB %s (%s)\n Id: %s\n", contact->friendlyName.c_str(), contact->userName.c_str(), contact->properties["contactId"].c_str()); +/* if(contact->properties["isMessengerUser"]=="false") + printf(" Not Messenger User\n"); + + std::list::iterator pns = contact->phoneNumbers.begin(); + std::list::iterator g = contact->groups.begin(); + for (; g != contact->groups.end(); g++) + { + printf(" G: %s\n", (*g)->name.c_str()); + } + + for (; pns != contact->phoneNumbers.end(); pns++) + { + printf(" %s: %s (%d)\n", (*pns).title.c_str(), (*pns).number.c_str(), (*pns).enabled); + }*/ + } + if(contact->lists & MSN::LST_AL ) + { + ic->permit = g_slist_append(ic->permit, g_strdup(user)); + + allContacts[contact->userName.c_str()]+=2; +// printf("-AL %s \n", contact->userName.c_str()); + } + + if(contact->lists & MSN::LST_BL ) + { + ic->deny = g_slist_append(ic->deny, g_strdup(user)); + + allContacts[contact->userName.c_str()]+=4; +// printf("-BL %s \n", contact->userName.c_str()); + } + + if(contact->lists & MSN::LST_RL ) + { +// if ((contact->lists & (MSN::LST_AL|MSN::LST_BL)) == 0) +// TODO medpri msn_buddy_ask(ic, user, contact->friendlyName.c_str()); + +// printf("-RL %s \n", contact->userName.c_str()); + } + if(contact->lists & MSN::LST_PL ) + { +// printf("-PL %s \n", contact->userName.c_str()); + } + } +/* printf("Available Groups:\n"); + std::map::iterator g = info->groups.begin(); + + for (; g != info->groups.end(); g++) + { + printf(" %s: %s\n", (*g).second.groupID.c_str(), (*g).second.name.c_str()); + } + + std::map::iterator b = allContacts.begin(); +*/ + // this will send the ADL command to the server + // It is necessary. Dont forget to add *all* your contacts to allContacts, + // (both Forward, allow and block lists) or you probably will + // loose someone. + // A contact cannot be present both on allow and block lists or the + // server will return an error, so you need to let your application + // choose the better list to put it in. + conn->completeConnection(allContacts,info); +} + +void Callbacks::gotLatestListSerial(MSN::NotificationServerConnection * conn, std::string lastChange) +{ + dbg("TODO lowpri%c", '\n'); + // The application needs to track this number to not ask for the whole contact + // list every login +// printf("The latest change number is: %s\n", lastChange.c_str()); +} + +void Callbacks::gotGTC(MSN::NotificationServerConnection * conn, char c) +{ + dbg("%c", '\n'); + printf("Your GTC value is now %c\n", c); +} + +void Callbacks::gotOIMDeleteConfirmation(MSN::NotificationServerConnection * conn, bool success, std::string id) +{ + dbg("%c", '\n'); + if (!success) + imcb_error(ic, "OIM %s not removed", id.c_str()); +/* if(success) + std::cout << "OIM "<< id << " removed sucessfully." << std::endl; + else + std::cout << "OIM "<< id << " not removed sucessfully." << std::endl; +*/ +} + +void Callbacks::gotOIMSendConfirmation(MSN::NotificationServerConnection * conn, bool success, int id) +{ + dbg("%c", '\n'); + if (!success) + imcb_error(ic, "Failed to send OIM"); + +/* if(success) + std::cout << "OIM " << id << " sent sucessfully." << std::endl; + else + std::cout << "OIM " << id << " not sent sucessfully." << std::endl; +*/ +} + +void Callbacks::gotOIM(MSN::NotificationServerConnection * conn, bool success, std::string id, std::string message) +{ + dbg("%c", '\n'); + if (success) { + imcb_log(ic, "Got OIM: id:%s, message:%s", id.c_str(), message.c_str()); + conn->delete_oim(id); + } else { + imcb_error(ic, "Failed to receive OIM with id %s", id.c_str()); + } +/* if(success) + std::cout << "ID: " << id << std::endl << "\t" << message << std::endl; + else + std::cout << "Error retreiving OIM " << id << std::endl; +*/ +} + +void Callbacks::gotOIMList(MSN::NotificationServerConnection * conn, std::vector OIMs) +{ + dbg("%c", '\n'); +/* if(OIMs.size()==0) + { + printf("No Offline messages\n"); + return; + }*/ + std::vector::iterator i = OIMs.begin(); + for(; iget_oim((*i).id, false /* don't mark as read */); + } +} + +void Callbacks::connectionReady(MSN::Connection * conn) +{ + dbg("%c", '\n'); + imcb_connected(ic); +// printf("The connection is ready. You can change your status now!\n"); +} + +void Callbacks::gotBLP(MSN::NotificationServerConnection * conn, char c) +{ + dbg("%c", '\n'); + printf("Your BLP value is now %cL\n", c); +} + +void Callbacks::addedListEntry(MSN::NotificationServerConnection * conn, MSN::ContactList list, MSN::Passport username, std::string friendlyname) +{ + dbg("%c", '\n'); + if(list == MSN::LST_RL) + // after adding the user you need to delete it from the pending list. + // it will be added automatically by the msn service + printf("%s is now on your list %d. FriendlyName: %s\n", username.c_str(), list, friendlyname.c_str()); + else + // on normal lists you'll never receive the contacts displayname + // it is not needed anyway + printf("%s is now on your list %d\n", username.c_str(), list); +} + +void Callbacks::removedListEntry(MSN::NotificationServerConnection * conn, MSN::ContactList list, MSN::Passport username) +{ + dbg("%c", '\n'); + // list is a number which matches with MSN::ContactList enum on util.h + printf("%s has been removed from list %d\n", username.c_str(), list); +} + +void Callbacks::addedGroup(MSN::NotificationServerConnection * conn, bool added, std::string groupName, std::string groupID) +{ + dbg("%c", '\n'); + if(added) + printf("A group named %s (%s) was added\n", groupName.c_str(), groupID.c_str()); + else + printf("Group (%s) was NOT added\n", groupName.c_str()); +} + +void Callbacks::removedGroup(MSN::NotificationServerConnection * conn, bool removed, std::string groupID) +{ + dbg("%c", '\n'); + if(removed) + printf("A group with ID %s was removed\n", groupID.c_str()); + else + printf("Group (%s) was NOT removed\n", groupID.c_str()); +} + +void Callbacks::renamedGroup(MSN::NotificationServerConnection * conn, bool renamed, std::string newGroupName, std::string groupID) +{ + dbg("%c", '\n'); + if(renamed) + printf("A group with ID %s was renamed to %s\n", groupID.c_str(), newGroupName.c_str()); + else + printf("A group with ID %s was NOT renamed to %s\n", groupID.c_str(), newGroupName.c_str()); +} + +void Callbacks::showError(MSN::Connection * conn, std::string msg) +{ + dbg("%c", '\n'); + // so... maybe this would be the place to send OIM. + // problems: don't know error code 217; no passport; no message + + imcb_error(ic, "MSN: Error: %s\n", msg.c_str()); +} + +void Callbacks::buddyChangedStatus(MSN::NotificationServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus status, unsigned int clientID, std::string msnobject) +{ + dbg("%c", '\n'); + + imcb_buddy_status(ic, buddy.c_str(), OPT_LOGGED_IN | (status!=MSN::STATUS_AVAILABLE ? OPT_AWAY : 0), MSN::buddyStatusToString(status).c_str(), NULL); + if (status != MSN::STATUS_INVISIBLE) + onlineu.insert(buddy); + else + dbg("STATUS_INVISIBLE\n"); + + + printf("%s (%s) is now %s\n", friendlyname.c_str(), buddy.c_str(), MSN::buddyStatusToString(status).c_str()); + if (clientID & MSN::SupportWebcam) + printf("\t Supports Webcam\n"); + if (clientID & MSN::VoiceClips) + printf("\t Supports VoiceClips\n"); + if (clientID & MSN::SupportDirectIM) + printf("\t Supports DirectIM\n"); + if (clientID & MSN::SharingFolders) + printf("\t Supports SharingFolders\n"); + if (clientID & MSN::MSNC1) + printf("\t Supports MSNC1\n"); + if (clientID & MSN::MSNC2) + printf("\t Supports MSNC2\n"); + if (clientID & MSN::MSNC3) + printf("\t Supports MSNC3\n"); + if (clientID & MSN::MSNC4) + printf("\t Supports MSNC4\n"); + if (clientID & MSN::MSNC5) + printf("\t Supports MSNC5\n"); + if (clientID & MSN::MSNC6) + printf("\t Supports MSNC6\n"); + if (clientID & MSN::MSNC7) + printf("\t Supports MSNC7\n"); + +// lastObject = msnobject; +} + +void Callbacks::buddyOffline(MSN::NotificationServerConnection * conn, MSN::Passport buddy) +{ + dbg("%c", '\n'); + imcb_buddy_status(ic, buddy.c_str(), 0, NULL, NULL); + onlineu.erase(buddy); +/* dbg("buddy: %s\n", buddy.c_str()); + std::set::iterator it = onlineu.begin(); + for (; it != onlineu.end(); it++) + dbg(":%s\n", (*it).c_str()); +*/ +// printf("%s is now offline\n", buddy.c_str()); +} + +void Callbacks::gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag) +{ + dbg("%c", '\n'); + +// printf("Got switchboard connection\n"); + if (tag) + { + const std::pair *ctx = static_cast *>(tag); + + /* there's also message to be sent */ + if (ctx->first[0] != ' ') { + dbg("%c", '\n'); + conn->inviteUser(ctx->first); + + /* only create groupchat (with 2 persons!) */ + } else { + dbg("%c", '\n'); + conn->inviteUser(ctx->first.substr(1)); // XXX + const std::pair *ctx = static_cast *>(tag); + + sb_chats[conn] = ctx->second; + sb_chats_r[ctx->second] = conn; + + delete ctx; + conn->auth.tag = NULL; // XXX ok, or is it set after this CB? + } + } +} + +void Callbacks::buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string friendlyname, int is_initial) +{ + // is_initial means "username" started the connection + dbg("is_initial: %i%c", is_initial, '\n'); + + /* one on one conversation? */ + if (is_initial || conn->auth.tag) { + sb_buddy_chats[conn] = username.c_str(); + sb_buddy_chats_r[username.c_str()] = conn; + } else { + sb_buddy_chats_r.erase(sb_buddy_chats[conn]); + sb_buddy_chats.erase(conn); + } + + /* 3rd person in a chat - create a channel */ + //if (conn->users.size() == 3 && sb_chats.count(conn) == 0) { + if (conn->users.size() == 2 && sb_chats.count(conn) == 0) { + sb_chats[conn] = imcb_chat_new(ic, ("MSN groupchat session " + conn->auth.sessionID).c_str()); + sb_chats_r[sb_chats[conn]] = conn; + + /* add everyone to channel */ + std::list::iterator it; + for (it = conn->users.begin(); it != conn->users.end(); it++) { + imcb_chat_add_buddy(sb_chats[conn], (*it).c_str()); + } + } + /* add a user to existing channel */ + else if (sb_chats.count(conn) > 0) { + imcb_chat_add_buddy(sb_chats[conn], username.c_str()); + } + + +// printf("%s (%s) is now in the session\n", friendlyname.c_str(), username.c_str()); + + /* handle the message sending, finally + * libmsn_buddy_msg -> gotSwitchboard -> buddyJoinedConversation + */ + if (conn->auth.tag) + { + const std::pair *ctx = static_cast *>(conn->auth.tag); + // Example of sending a custom emoticon +// conn->myNotificationServer()->msnobj.addMSNObject("/tmp/emoticon.gif",2); +// std::string obj; +// conn->myNotificationServer()->msnobj.getMSNObjectXML("/tmp/emoticon.gif", 2, obj); +// conn->sendEmoticon("(EMOTICON)", obj); + + /*int trid = */conn->sendMessage(ctx->second); +// std::cout << "Message " << trid << " queued" << std::endl; + delete ctx; + conn->auth.tag = NULL; + + //Example of sending a file +// MSN::fileTransferInvite ft; +// ft.filename = "/tmp/filetosend.txt"; +// ft.friendlyname = "filetosend2.txt"; +// ft.sessionId = sessionID++; +// ft.type = MSN::FILE_TRANSFER_WITHOUT_PREVIEW; +// conn->sendFile(ft); + +// conn->sendNudge(); +// conn->sendAction("Action message here"); + + // Exemple of requesting a display picture. +// std::string filename2("/tmp/displayPicture.bin"+MSN::toStr(sessionID)); + // lastObject is the msnobject received on each contact status change + // you should generate a random sessionID +// conn->requestDisplayPicture(sessionID++, filename2, lastObject); + + // Example of sending a voice clip +// conn->myNotificationServer()->msnobj.addMSNObject("/tmp/voiceclip.wav",11); +// std::string obj; +// conn->myNotificationServer()->msnobj.getMSNObjectXML("/tmp/voiceclip.wav", 11, obj); +// conn->sendVoiceClip(obj); + // exemple of sending an ink +// std::string ink("base64 data here..."); +// conn->sendInk(ink); + } +} + +void Callbacks::buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport username) +{ + dbg("%c", '\n'); + + if (sb_buddy_chats.count(conn)) { + sb_buddy_chats_r.erase(sb_buddy_chats[conn]); + sb_buddy_chats.erase(conn); + } + + if (sb_chats.count(conn)) { + imcb_chat_remove_buddy(sb_chats[conn], username.c_str(), ""); + + /* last person left, delete the channel (if it existed) */ + if (conn->users.size() == 0) { //XXX == 1? + imcb_chat_free(sb_chats[conn]); + sb_chats_r.erase(sb_chats[conn]); + sb_chats.erase(conn); + } + } + + printf("%s has now left the session\n", username.c_str()); +} + +void Callbacks::gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string friendlyname, MSN::Message * msg) +{ + dbg("%c", '\n'); + char *msgstr = g_strdup(msg->getBody().c_str()); + + /* groupchat? */ + if (sb_chats.count(conn)) { + imcb_chat_msg(sb_chats[conn], username.c_str(), msgstr, 0, 0); + } else { + imcb_buddy_msg(ic, username.c_str(), msgstr, 0, 0); + } + + g_free(msgstr); + +// printf("--- Message from %s (%s) in font %s:\n%s\n", friendlyname.c_str(), username.c_str(), msg->getFontName().c_str(), msg->getBody().c_str()); +} + +void Callbacks::gotEmoticonNotification(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string alias, std::string msnobject) +{ + dbg("%c", '\n'); + std::string filename2("/tmp/emoticon.bin"+MSN::toStr(sessionID)); + printf("--- Emoticon '%s' from %s -> %s\n", alias.c_str(), username.c_str(), msnobject.c_str()); + conn->requestFile(sessionID++, filename2, msnobject); +} + +void Callbacks::failedSendingMessage(MSN::Connection * conn) +{ + dbg("%c", '\n'); + // TODO highpri + printf("**************************************************\n"); + printf("ERROR: Your last message failed to send correctly\n"); + printf("**************************************************\n"); +} + +void Callbacks::buddyTyping(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string friendlyname) +{ + dbg("%c", '\n'); + printf("\t%s (%s) is typing...\n", friendlyname.c_str(), username.c_str()); + +} + +void Callbacks::gotNudge(MSN::SwitchboardServerConnection * conn, MSN::Passport username) +{ + dbg("%c", '\n'); + printf("\t%s sent you a nudge ...\n", username.c_str()); +} + +void Callbacks::gotVoiceClip(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string msnobject) +{ + dbg("%c", '\n'); + printf("\t%s sent you a voice clip...\n", username.c_str()); + std::string filename2("/tmp/voiceclip.bin"+MSN::toStr(sessionID)); + conn->requestFile(sessionID++, filename2, msnobject); +} + +void Callbacks::gotWink(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string msnobject) +{ + dbg("%c", '\n'); + printf("\t%s sent you a Wink...\n", username.c_str()); + std::string filename2("/tmp/wink.bin"+MSN::toStr(sessionID)); + // you should generate a random sessionID number + conn->requestFile(sessionID++, filename2, msnobject); +} + +void Callbacks::gotInk(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string image) +{ + dbg("%c", '\n'); + // image variable is the base64 encoded gif file + printf("\t%s sent you an Ink...\n", username.c_str()); +// std::string filename2("/tmp/ink.bin"+MSN::toStr(sessionID)); + // you should generate a random sessionID number +// conn->requestFile(sessionID++, filename2, msnobject); +} + +void Callbacks::gotContactDisplayPicture(MSN::SwitchboardServerConnection * conn, MSN::Passport passport, std::string filename ) +{ + dbg("%c", '\n'); + printf("Received display picture from %s. File: %s\n", passport.c_str(), filename.c_str()); +} + +void Callbacks::gotActionMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string message) +{ + dbg("%c", '\n'); + printf("\t%s sent you an action message: %s\n", username.c_str(), message.c_str()); +} + +void Callbacks::gotInitialEmailNotification(MSN::NotificationServerConnection * conn, int msgs_inbox, int unread_inbox, int msgs_folders, int unread_folders) +{ + dbg("%c", '\n'); + if (unread_inbox > 0) + printf("You have %d new messages in your Inbox. Total: %d\n", unread_inbox, msgs_inbox); + + if (unread_folders > 0) + printf("You have %d new messages in other folders. Total: %d\n", unread_folders, msgs_folders); +} + +void Callbacks::gotNewEmailNotification(MSN::NotificationServerConnection * conn, std::string from, std::string subject) +{ + dbg("%c", '\n'); + printf("New e-mail has arrived from %s.\nSubject: %s\n", from.c_str(), subject.c_str()); +} + +void Callbacks::gotFileTransferInvitation(MSN::Connection *conn, MSN::Passport username, std::string friendlyname, MSN::FileTransferInvitation * inv) +{ + dbg("%c", '\n'); + printf("Got file transfer invitation from %s (%s)\n", friendlyname.c_str(), username.c_str()); + inv->acceptTransfer("tmp.out"); +} + +void Callbacks::fileTransferInviteResponse(MSN::FileTransferInvitation *inv, unsigned int sessionID, bool response) +{ + dbg("%c", '\n'); + if(response) + printf("Session accepted %d: \n", sessionID); + else + printf("Session not accepted %d: \n", sessionID); +} + +void Callbacks::fileTransferProgress(MSN::FileTransferInvitation *inv, unsigned int sessionID, std::string status, unsigned long long transferred, unsigned long long total) +{ + dbg("%c", '\n'); + printf("File transfer: session %d\t(%llu/%llu bytes sent/received)\n", sessionID, transferred, total); +} + +void Callbacks::fileTransferFailed(MSN::FileTransferInvitation * inv, unsigned int sessionID, int error, std::string message) +{ + dbg("%c", '\n'); + printf("File transfer failed: %s\n", message.c_str()); +} + +void Callbacks::fileTransferSucceeded(MSN::FileTransferInvitation *inv, unsigned int sessionID) +{ + dbg("%c", '\n'); + printf("File transfer successfully completed. session: %d\n", sessionID); +} + +void Callbacks::gotNewConnection(MSN::Connection * conn) +{ +// imcb_log(ic, "Established connection to server"); +// dbg("%c", '\n'); + if (dynamic_cast(conn)) + dynamic_cast(conn)->synchronizeContactList(); +} + +void Callbacks::buddyChangedPersonalInfo(MSN::NotificationServerConnection * conn, MSN::Passport fromPassport, MSN::personalInfo pInfo) +{ + dbg("%c", '\n'); + // MSN::personalInfo shows all the data you can grab from the contact + printf("User %s Personal Message: %s\n", fromPassport.c_str(),pInfo.PSM.c_str()); +} + +void Callbacks::closingConnection(MSN::Connection * conn) +{ + dbg("%c", '\n'); + /* sock == -1? */ + printf("Closed connection with socket %d\n", conn->sock); +} + +void Callbacks::changedStatus(MSN::NotificationServerConnection * conn, MSN::BuddyStatus state) +{ + dbg("%c", '\n'); + printf("Your state is now: %s\n", MSN::buddyStatusToString(state).c_str()); +/* + MSN::personalInfo pInfo; + pInfo.PSM="my personal message"; + pInfo.mediaType="Music"; + pInfo.mediaIsEnabled=1; + pInfo.mediaFormat="{0} - {1}"; + pInfo.mediaLines.push_back("Artist"); + pInfo.mediaLines.push_back("Song"); + conn->setPersonalStatus(pInfo); + */ +} + +int Callbacks::connectToServer(std::string hostname, int port, bool *connected) +{ + dbg("%s:%i\n", hostname.c_str(), port); + struct sockaddr_in sa; + struct hostent *hp; + int s; + int oldfdArgs; + + if ((hp = gethostbyname(hostname.c_str())) == NULL) { + errno = ECONNREFUSED; + goto i_has_fail; + } + + memset(&sa,0,sizeof(sa)); + memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); /* set address */ + sa.sin_family = hp->h_addrtype; + sa.sin_port = htons((u_short)port); + + if ((s = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) /* get socket */ + goto i_has_fail; + + oldfdArgs = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, oldfdArgs | O_NONBLOCK); + + if (connect(s,(struct sockaddr *)&sa,sizeof sa) < 0) + { + if (errno != EINPROGRESS) + { + close(s); + goto i_has_fail; + } + *connected = false; + } + else + *connected = true; + + return s; + +i_has_fail: + /* error printed in showError cb */ + imc_logout(ic, TRUE); + /* XXX destroy class */ + return -1; +} + +int Callbacks::listenOnPort(int port) +{ + dbg("port:%i", port); + int s; + struct sockaddr_in addr; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + if (bind(s, (sockaddr *)(&addr), sizeof(addr)) < 0 || listen(s, 1) < 0) + { + close(s); + return -1; + } + + return s; +} + +std::string Callbacks::getOurIP(void) +{ + dbg("%c", '\n'); + struct hostent * hn; + char buf2[1024]; + + gethostname(buf2,1024); + hn = gethostbyname(buf2); + + return inet_ntoa( *((struct in_addr*)hn->h_addr)); +} + +void Callbacks::log(int i, const char *s) +{ +// dbg("%i:%s%c", i, s, '\n'); + +} + +std::string Callbacks::getSecureHTTPProxy() +{ + dbg("%c", '\n'); + return ""; +} + +void Callbacks::gotMessageSentACK(MSN::SwitchboardServerConnection * conn, int trID) +{ + dbg("%c", '\n'); +// std::cout << "Message " << trID << " delivered" << std::endl; +} + +void Callbacks::askFileTransfer(MSN::SwitchboardServerConnection * conn, MSN::fileTransferInvite ft) +{ + dbg("%c", '\n'); + std::string filename2("/tmp/"+ft.filename); + switch(ft.type) + { + case MSN::FILE_TRANSFER_BACKGROUND_SHARING: + printf("User %s wants to share with you a background file named %s. Size: %llu. Accepting..\n", ft.userPassport.c_str(), ft.filename.c_str(), ft.filesize); + break; + case MSN::FILE_TRANSFER_BACKGROUND_SHARING_CUSTOM: + printf("User %s wants to share with you a *custom background file named %s. Size: %llu. Accepting..\n", ft.userPassport.c_str(), ft.filename.c_str(), ft.filesize); + break; + case MSN::FILE_TRANSFER_WITH_PREVIEW: + printf("User %s wants to send you a file *with preview named %s. Size: %llu. Accepting..\n", ft.userPassport.c_str(), ft.filename.c_str(), ft.filesize); + // ft.preview has the base64 encoded png file + break; + case MSN::FILE_TRANSFER_WITHOUT_PREVIEW: + printf("User %s wants to send you a file *without preview named %s. Size: %llu. Accepting..\n", ft.userPassport.c_str(), ft.filename.c_str(), ft.filesize); + break; + default: + printf("Unknown filetransfer type from %s..\n", ft.userPassport.c_str()); + + } + conn->fileTransferResponse(ft.sessionId, filename2, true); +} + +void Callbacks::addedContactToGroup(MSN::NotificationServerConnection * conn, bool added, std::string groupId, std::string contactId) +{ + dbg("%c", '\n'); + if(added) + printf("User Id (%s) added to group Id (%s)\n", contactId.c_str(),groupId.c_str()); + else + printf("User Id (%s) NOT added to group Id (%s)\n", contactId.c_str(),groupId.c_str()); +} + +void Callbacks::removedContactFromGroup(MSN::NotificationServerConnection * conn, bool removed, std::string groupId, std::string contactId) +{ + dbg("%c", '\n'); + if(removed) + printf("User Id (%s) removed from group Id (%s)\n", contactId.c_str(),groupId.c_str()); + else + printf("User Id (%s) NOT removed from group Id (%s)\n", contactId.c_str(),groupId.c_str()); +} + +void Callbacks::addedContactToAddressBook(MSN::NotificationServerConnection * conn, bool added, std::string passport, std::string displayName, std::string guid) +{ + dbg("%c", '\n'); + if(added) { + imcb_add_buddy(ic, passport.c_str(), NULL); + imcb_rename_buddy(ic, passport.c_str(), displayName.c_str()); + contactids[passport] = guid; + +// printf("User (%s - %s) added to AddressBook. Guid (%s)\n", passport.c_str(),displayName.c_str(), guid.c_str()); + } else + printf("User (%s - %s) NOT added to AddressBook.\n", passport.c_str(),displayName.c_str()); +} + +void Callbacks::removedContactFromAddressBook(MSN::NotificationServerConnection * conn, bool removed, std::string contactId, std::string passport) +{ + dbg("%c", '\n'); + if(removed) { + imcb_remove_buddy(ic, passport.c_str(), NULL); +// printf("User %s removed from AddressBook. Guid (%s)\n", passport.c_str(), contactId.c_str()); + } else + printf("User %s NOT removed from AddressBook. Guid (%s)\n", passport.c_str(), contactId.c_str()); +} + +void Callbacks::enabledContactOnAddressBook(MSN::NotificationServerConnection * conn, bool enabled, std::string contactId, std::string passport) +{ + dbg("%c", '\n'); + // this is used to enable a contact previously disabled from msn, but not fully removed + if(enabled) + printf("User (%s) enabled on AddressBook. Guid (%s)\n", passport.c_str(), contactId.c_str()); + else + printf("User (%s) NOT enabled on AddressBook. Guid (%s)\n", passport.c_str(), contactId.c_str()); +} + +void Callbacks::disabledContactOnAddressBook(MSN::NotificationServerConnection * conn, bool disabled, std::string contactId) +{ + dbg("%c", '\n'); + // this is used when you have disabled this user from msn, but not deleted from hotmail + // I suggest to delete the contact instead of disable, since I haven't tested this too much yet + if(disabled) + printf("User disabled on AddressBook. Guid (%s)\n", contactId.c_str()); + else + printf("User NOT disabled on AddressBook. Guid (%s)\n", contactId.c_str()); +} Index: bitlbee-bzr-main-409/protocols/libmsn/msn_callbacks.h =================================================================== --- /dev/null +++ bitlbee-bzr-main-409/protocols/libmsn/msn_callbacks.h @@ -0,0 +1,100 @@ +#ifndef MSN_CALLBACKS +#define MSN_CALLBACKS + +#include // struct pollfd +#include + +struct im_connection; + +class Callbacks: public MSN::Callbacks { +private: + struct im_connection *ic; + +public: + /* list of groupchats */ + std::map sb_chats; + std::map sb_chats_r; + /* list of 1-1 chats */ + std::map sb_buddy_chats; + std::map sb_buddy_chats_r; + + /* online users */ + std::set onlineu; + + /* all contacts with their ids */ + /* map */ + std::map contactids; + + std::string myFriendlyName; + +private: + + // key - fd, data - event + std::multimap sockets; + + unsigned int sessionID; + +public: + Callbacks(struct im_connection *ic); + virtual ~Callbacks(); + void registerSocket(int fd, int read, int write); + void unregisterSocket(int fd); + void closeSocket(int fd); + void showError(MSN::Connection * conn, std::string msg); + void buddyChangedStatus(MSN::NotificationServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus state, unsigned int clientID, std::string msnobject); + void buddyOffline(MSN::NotificationServerConnection * conn, MSN::Passport buddy); + void log(int writing, const char* buf); + void buddyChangedPersonalInfo(MSN::NotificationServerConnection * conn, MSN::Passport fromPassport, MSN::personalInfo); + void gotFriendlyName(MSN::NotificationServerConnection * conn, std::string friendlyname); + void gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data); + void gotLatestListSerial(MSN::NotificationServerConnection * conn, std::string lastChange); + void gotGTC(MSN::NotificationServerConnection * conn, char c); + void gotBLP(MSN::NotificationServerConnection * conn, char c); + void addedListEntry(MSN::NotificationServerConnection * conn, MSN::ContactList list, MSN::Passport buddy, std::string friendlyname); + void removedListEntry(MSN::NotificationServerConnection * conn, MSN::ContactList list, MSN::Passport buddy); + void addedGroup(MSN::NotificationServerConnection * conn, bool added, std::string groupName, std::string groupID); + void removedGroup(MSN::NotificationServerConnection * conn, bool removed, std::string groupID); + void renamedGroup(MSN::NotificationServerConnection * conn, bool renamed, std::string newGroupName, std::string groupID); + void addedContactToGroup(MSN::NotificationServerConnection * conn, bool added, std::string groupId, std::string contactId); + void removedContactFromGroup(MSN::NotificationServerConnection * conn, bool removed, std::string groupId, std::string contactId); + void addedContactToAddressBook(MSN::NotificationServerConnection * conn, bool added, std::string passport, std::string displayName, std::string guid); + void removedContactFromAddressBook(MSN::NotificationServerConnection * conn, bool removed, std::string contactId, std::string passport); + void enabledContactOnAddressBook(MSN::NotificationServerConnection * conn, bool enabled, std::string contactId, std::string passport); + void disabledContactOnAddressBook(MSN::NotificationServerConnection * conn, bool disabled, std::string contactId); + void gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag); + void buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial); + void buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy); + void gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg); + void gotMessageSentACK(MSN::SwitchboardServerConnection * conn, int trID); + void gotEmoticonNotification(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string alias, std::string msnobject); + void failedSendingMessage(MSN::Connection * conn); + void buddyTyping(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname); + void gotNudge(MSN::SwitchboardServerConnection * conn, MSN::Passport from); + void gotVoiceClip(MSN::SwitchboardServerConnection * conn, MSN::Passport from, std::string msnobject); + void gotWink(MSN::SwitchboardServerConnection * conn, MSN::Passport from, std::string msnobject); + void gotInk(MSN::SwitchboardServerConnection * conn, MSN::Passport from, std::string image); + void gotActionMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string message); + void gotInitialEmailNotification(MSN::NotificationServerConnection * conn, int msgs_inbox, int unread_inbox, int msgs_folders, int unread_folders); + void gotNewEmailNotification(MSN::NotificationServerConnection * conn, std::string from, std::string subject); + void gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv); + void fileTransferProgress(MSN::FileTransferInvitation * inv, unsigned int sessionID, std::string status, long long unsigned transferred, long long unsigned total); + void fileTransferFailed(MSN::FileTransferInvitation * inv, unsigned int sessionID, int error, std::string message); + void fileTransferSucceeded(MSN::FileTransferInvitation *inv, unsigned int sessionID); + void fileTransferInviteResponse(MSN::FileTransferInvitation *inv, unsigned int sessionID, bool response); + void gotNewConnection(MSN::Connection * conn); + void gotOIMList(MSN::NotificationServerConnection * conn, std::vector OIMs); + void gotOIM(MSN::NotificationServerConnection * conn, bool success, std::string id, std::string message); + void gotOIMSendConfirmation(MSN::NotificationServerConnection * conn, bool success, int id); + void gotOIMDeleteConfirmation(MSN::NotificationServerConnection * conn, bool success, std::string id); + void gotContactDisplayPicture(MSN::SwitchboardServerConnection * conn, MSN::Passport passport, std::string filename ); + void closingConnection(MSN::Connection * conn); + void changedStatus(MSN::NotificationServerConnection * conn, MSN::BuddyStatus state); + int connectToServer(std::string server, int port, bool *connected); + void connectionReady(MSN::Connection * conn); + void askFileTransfer(MSN::SwitchboardServerConnection *conn, MSN::fileTransferInvite ft); + int listenOnPort(int port); + std::string getOurIP(); + std::string getSecureHTTPProxy(); +}; + +#endif Index: bitlbee-bzr-main-409/protocols/nogaim.c =================================================================== --- bitlbee-bzr-main-409.orig/protocols/nogaim.c +++ bitlbee-bzr-main-409/protocols/nogaim.c @@ -117,6 +117,7 @@ void nogaim_init() extern void oscar_initmodule(); extern void byahoo_initmodule(); extern void jabber_initmodule(); + extern void libmsn_initmodule(); #ifdef WITH_MSN msn_initmodule(); @@ -134,6 +135,10 @@ void nogaim_init() jabber_initmodule(); #endif +#ifdef WITH_LIBMSN + libmsn_initmodule(); +#endif + #ifdef WITH_PLUGINS load_plugins(); #endif