Changeset - 3724ba2c0ce5
.gitignore
Show inline comments
 
new file 100644
 
*.pb.cc
 
*.pb.h
 
plugin/python/protocol_pb2.py
 
\ No newline at end of file
CMakeLists.txt
Show inline comments
 
cmake_minimum_required(VERSION 2.6)
 
project(libtransport)
 

	
 
message(STATUS "Variables to override default places where to find libraries:")
 
message(STATUS "|- cppunit : -DCPPUNIT_INCLUDE_DIR,  -DCPPUNIT_LIBRARY")
 
message(STATUS "|- swiften : -DSWIFTEN_INCLUDE_DIR,  -DSWIFTEN_LIBRARY")
 
message(STATUS "  |- zlib  :                         -DZLIB_LIBRARY")
 
message(STATUS "  |- expat :                         -DEXPAT_LIBRARY")
 
message(STATUS "  |-libidn :                         -DLIBIDN_LIBRARY")
 
message(STATUS "  |-libxml :                         -DLIBXML_LIBRARY")
 
message(STATUS "|- boost   : -DBOOST_INCLUDEDIR,     -DBOOST_LIBRARYDIR")
 
message(STATUS "|- protobuf: -DPROTOBUF_INCLUDE_DIR, -DPROTOBUF_LIBRARY")
 
message(STATUS "           : -DPROTOBUF_PROTOC_EXECUTABLE")
 
message(STATUS "|- log4cxx : -DLOG4CXX_INCLUDE_DIR,  -DLOG4CXX_LIBRARY")
 
message(STATUS "|- purple  : -DPURPLE_INCLUDE_DIR,   -DPURPLE_LIBRARY")
 
message(STATUS "           : -DPURPLE_NOT_RUNTIME - enables compilation with libpurple.lib")
 

	
 
if(NOT LIB_INSTALL_DIR)
 
	set(LIB_INSTALL_DIR "lib")
 
endif()
 

	
 
set(CMAKE_MODULE_PATH "cmake_modules")
 

	
 
# FIND CPPUNIT
 
set(cppunit_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(cppunit)
 

	
 
if(NOT CPPUNIT_FOUND AND CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARY)
 
	set(CCPUNIT_LIBRARIES ${CPPUNIT_LIBRARY})
 
	set(CPPUNIT_FOUND 1)
 
	message(STATUS "Using cppunit: ${CPPUNIT_INCLUDE_DIR} ${CPPUNIT_LIBRARIES}")
 
else()
 

	
 
endif()
 

	
 
# FIND SQLITE3
 
if (NOT CMAKE_COMPILER_IS_GNUCXX)
 
ADD_SUBDIRECTORY(msvc-deps)
 
else()
 
if (WIN32)
 
ADD_SUBDIRECTORY(msvc-deps/sqlite3)
 
else()
 
set(sqlite3_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(sqlite3)
 
endif()
 
endif()
 

	
 
# FIND MYSQL
 
set(mysql_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(mysql)
 

	
 
# FIND LIBPURPLE
 
set(purple_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(purple)
 

	
 
set(glib_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(glib)
 
if (WIN32)
 
	if (PURPLE_NOT_RUNTIME)
 
		add_definitions(-DPURPLE_RUNTIME=0)
 
	else(PURPLE_NOT_RUNTIME)
 
		add_definitions(-DPURPLE_RUNTIME=1)
 
	endif(PURPLE_NOT_RUNTIME)
 
else()
 
	add_definitions(-DPURPLE_RUNTIME=0)
 
endif()
 

	
 
# FIND GLIB
 
# if (GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
 
# 	set(GLIB2_FOUND TRUE)
 
# else()
 
	set(glib_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
	find_package(glib)
 
# endif()
 

	
 
# FIND LIBXML2
 
# set(libxml2_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
# find_package(libxml2)
 

	
 
# FIND POPT
 
if (NOT WIN32)
 
	set(popt_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
	find_package(popt)
 
endif()
 

	
 
# FIND LIBEVENT
 
set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(event)
 

	
 
# FIND SWIFTEN
 

	
 
set(Swiften_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Swiften)
 

	
 
if(NOT SWIFTEN_FOUND)
 
	if (ZLIB_LIBRARY)
 
		set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} ${ZLIB_LIBRARY})
 
	endif()
 
	if (EXPAT_LIBRARY)
 
		set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} ${EXPAT_LIBRARY})
 
	endif()
 
	if (LIBIDN_LIBRARY)
 
		set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} ${LIBIDN_LIBRARY})
 
	endif()
 
	if (LIBXML_LIBRARY)
 
		set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} ${LIBXML_LIBRARY})
 
	endif()
 
	set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} "Dnsapi")
 
	set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} "Crypt32")
 
	set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} "Secur32")
 
	set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} "Iphlpapi")
 
	set(SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY} "Winscard")
 
	message(STATUS "Using swiften: ${SWIFTEN_INCLUDE_DIR} ${SWIFTEN_LIBRARY}")
 
endif()
 

	
 
if (WIN32)
 
	add_definitions(-DSWIFTEN_STATIC=1)
 
	ADD_DEFINITIONS(-D_UNICODE)
 
	ADD_DEFINITIONS(-DUNICODE)
 
endif()
 

	
 

	
 
if (CMAKE_COMPILER_IS_GNUCXX)
 
set(openssl_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(openssl)
 
endif()
 

	
 
# FIND BOOST
 
set(Boost_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
if (WIN32)
 
set(Boost_USE_STATIC_LIBS        ON)
 
set(Boost_USE_MULTITHREADED      ON)
 
set(Boost_USE_STATIC_RUNTIME    OFF)
 
endif()
 
find_package(Boost COMPONENTS program_options date_time system filesystem regex  signals REQUIRED)
 
	set(Boost_USE_STATIC_LIBS      ON)
 
	set(Boost_USE_MULTITHREADED      ON)
 
	set(Boost_USE_STATIC_RUNTIME    OFF)
 
	find_package(Boost COMPONENTS program_options date_time system filesystem regex thread signals REQUIRED)
 
else(WIN32)
 
	find_package(Boost COMPONENTS program_options date_time system filesystem regex thread signals REQUIRED)
 
endif(WIN32)
 

	
 
message( STATUS "Found Boost: ${Boost_LIBRARIES}, ${Boost_INCLUDE_DIR}")
 

	
 
set(Protobuf_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Protobuf REQUIRED)
 
find_package(Protobuf)
 

	
 
# FIND PROTOBUF
 
if (NOT PROTOBUF_FOUND AND PROTOBUF_INCLUDE_DIR AND PROTOBUF_LIBRARY)
 
	set(PROTOBUF_FOUND 1)
 
	set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
 
	if (PROTOBUF_PROTOC_EXECUTABLE)
 
	else()
 
		set(PROTOBUF_PROTOC_EXECUTABLE protoc)
 
	endif()
 
	message(STATUS "Using protobuf: ${PROTOBUF_INCLUDE_DIRS} ${PROTOBUF_LIBRARY}")
 
endif()
 

	
 

	
 
set(Communi_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Communi)
 

	
 
set(log4cxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(log4cxx)
 
if(LOG4CXX_INCLUDE_DIR AND LOG4CXX_LIBRARY)
 
	set(LOG4CXX_LIBRARIES ${LOG4CXX_LIBRARY})
 
	set(LOG4CXX_FOUND 1)
 
	message(STATUS "Using log4cxx: ${CPPUNIT_INCLUDE_DIR} ${LOG4CXX_INCLUDE_DIR}")
 
else()
 
	set(log4cxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
	find_package(log4cxx)
 
endif()
 

	
 
set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(event)
 
@@ -60,8 +169,13 @@ find_package(event)
 
set(pqxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(pqxx)
 

	
 
if (NOT WIN32)
 
set(dbus_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(dbus)
 
endif()
 

	
 
set(yahoo2_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(yahoo2)
 

	
 
find_package(Doxygen)
 

	
 
@@ -70,7 +184,7 @@ FIND_PACKAGE(Qt4 COMPONENTS QtCore QtNetwork)
 

	
 
# ADD_DEFINITIONS(${SWIFTEN_CFLAGS})
 
ADD_DEFINITIONS(-DSUPPORT_LEGACY_CAPS)
 
ADD_DEFINITIONS(-DBOOST_FILESYSTEM_VERSION=2)
 
# ADD_DEFINITIONS(-DBOOST_FILESYSTEM_VERSION=2)
 

	
 
message("  Supported features")
 
message("-----------------------")
 
@@ -79,7 +193,10 @@ if (SPECTRUM_VERSION)
 
	ADD_DEFINITIONS(-DSPECTRUM_VERSION="${SPECTRUM_VERSION}")
 
else (SPECTRUM_VERSION)
 
	if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
 
		execute_process(COMMAND git "--git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git" rev-parse --short HEAD
 
		if (NOT GIT_EXECUTABLE)
 
		set (GIT_EXECUTABLE git)
 
		endif()
 
		execute_process(COMMAND ${GIT_EXECUTABLE} "--git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git" rev-parse --short HEAD
 
						OUTPUT_VARIABLE GIT_REVISION
 
						OUTPUT_STRIP_TRAILING_WHITESPACE
 
		)
 
@@ -98,8 +215,14 @@ if (SQLITE3_FOUND)
 
	include_directories(${SQLITE3_INCLUDE_DIR})
 
	message("SQLite3           : yes")
 
else (SQLITE3_FOUND)
 
if (WIN32)
 
	ADD_DEFINITIONS(-DWITH_SQLITE)
 
	include_directories(msvc-deps/sqlite3)
 
	message("SQLite3           : bundled")
 
else()
 
	set(SQLITE3_LIBRARIES "")
 
	message("SQLite3           : no")
 
endif()
 
endif (SQLITE3_FOUND)
 

	
 
if (MYSQL_FOUND)
 
@@ -126,7 +249,7 @@ if (PROTOBUF_FOUND)
 
	include_directories(${PROTOBUF_INCLUDE_DIRS})
 
	message("Network plugins   : yes")
 

	
 
	if(PURPLE_LIBRARY AND PURPLE_INCLUDE_DIR)
 
	if(PURPLE_FOUND)
 
		message("Libpurple plugin  : yes")
 
		include_directories(${PURPLE_INCLUDE_DIR})
 
		include_directories(${GLIB2_INCLUDE_DIR})
 
@@ -152,15 +275,31 @@ if (PROTOBUF_FOUND)
 
		message("IRC plugin        : no (install libCommuni and libprotobuf-dev)")
 
	endif()
 

	
 
if (NOT WIN32)
 
	message("Frotz plugin      : yes")
 
	message("SMSTools3 plugin  : yes")
 

	
 
	if(${LIBDBUSGLIB_FOUND})
 
		message("Skype plugin      : yes")
 
		include_directories(${LIBDBUSGLIB_INCLUDE_DIRS})
 
	else()
 
		message("Skype plugin      : no (install dbus-glib-devel)")
 
	endif()
 
else()
 
	message("Frotz plugin      : no")
 
	message("SMSTools3 plugin  : no")
 
	message("Skype plugin      : no")
 
endif()
 

	
 
#	We have our own copy now...
 
# 	if(YAHOO2_FOUND)
 
		message("Libyahoo2 plugin  : yes")
 
# 		include_directories(${YAHOO2_INCLUDE_DIR})
 
# 	else()
 
# 		message("Libyahoo2 plugin  : no (install libyahoo2-devel)")
 
# 	endif()
 

	
 
	message("Swiften plugin    : yes")
 
    message("Twitter plugin    : yes")
 

	
 
else()
 
	message("Network plugins   : no (install libprotobuf-dev)")
 
@@ -168,6 +307,8 @@ else()
 
	message("IRC plugin        : no (install libircclient-qt and libprotobuf-dev)")
 
	message("Frotz plugin      : no (install libprotobuf-dev)")
 
	message("SMSTools3 plugin  : no (install libprotobuf-dev)")
 
	message("Swiften plugin    : no (install libprotobuf-dev)")
 
    message("Twitter plugin    : no (install libprotobuf-dev)")
 
endif()
 

	
 
if (LOG4CXX_FOUND)
 
@@ -180,25 +321,17 @@ else()
 
endif()
 

	
 
if (WIN32)
 
ADD_DEFINITIONS(-DLOG4CXX_STATIC)
 
ADD_DEFINITIONS(-D_WIN32_WINNT=0x501)
 
ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN)
 
ADD_DEFINITIONS(-DBOOST_USE_WINDOWS_H)
 
ADD_DEFINITIONS(-DBOOST_THREAD_USE_LIB)
 
endif()
 

	
 
if(CMAKE_BUILD_TYPE MATCHES Debug)
 
if (CMAKE_COMPILER_IS_GNUCXX)
 
	ADD_DEFINITIONS(-O3)
 
	ADD_DEFINITIONS(-O0)
 
	ADD_DEFINITIONS(-ggdb)
 
	ADD_DEFINITIONS(-Wall)
 
	ADD_DEFINITIONS(-W)
 
	ADD_DEFINITIONS(-Wcast-align)
 
	ADD_DEFINITIONS(-Wextra -Wno-sign-compare -Wno-unused-parameter)
 
	ADD_DEFINITIONS(-Winit-self)
 
	ADD_DEFINITIONS(-Wmissing-declarations)
 
	ADD_DEFINITIONS(-Wpointer-arith)
 
	ADD_DEFINITIONS(-Wreorder)
 
	ADD_DEFINITIONS(-Woverloaded-virtual)
 
	ADD_DEFINITIONS(-Wsign-promo)
 
	ADD_DEFINITIONS(-Wundef -Wunused)
 
endif()
 
	ADD_DEFINITIONS(-DDEBUG)
 
	message("Debug             : yes")
 
@@ -215,7 +348,10 @@ include_directories(include)
 
include_directories(${EVENT_INCLUDE_DIRS})
 
include_directories(${SWIFTEN_INCLUDE_DIR})
 
include_directories(${Boost_INCLUDE_DIRS})
 

	
 
if (CMAKE_COMPILER_IS_GNUCXX)
 
include_directories(${OPENSSL_INCLUDE_DIR})
 
endif()
 

	
 
ADD_SUBDIRECTORY(src)
 
ADD_SUBDIRECTORY(plugin)
ChangeLog
Show inline comments
 
@@ -13,13 +13,42 @@ Version 2.0.0-beta3 (2012-XX-XX):
 
	* Added Munin plugin (Thanks to Askovpen).
 
	* Added support for more admin_jid JIDs (Thanks to Askovpen).
 
	* Fixed allowed_servers option.
 
	* Show error in server-mode when server port is already used.
 
	* Fixed bug when backend could freeze on exit.
 
	* Options from config file can now be set also using command line like
 
	  --service.jid=domain.tld .
 
	* Do not send password in IQ-get registration response.
 
	* Added support for AdHoc commands.
 
	* Do not store buddies with empty name in database.
 
	* Improved MySQL storage backend performance.
 
	* Do not handle error messages as normal ones.
 
	* Added Munin script for Spectrum 2.
 
	* Use utf-8 encoding as default for MySQL.
 
	* Added a way to disable xhtml-im.
 
	* Fix crash caused by two XMPP users using single PurpleAccount instance.
 
	* Support for [registration] allowed_usernames.
 
	* Fixed compilation with boost-1.50.
 

	
 
	Spectrum2_manager:
 
	* Rewritten to provide more features. Check the documentation.
 

	
 
	Libpurple:
 
	* prpl-gg: Fetch the contact list properly (#252).
 
	* Added support for prpl-novell as it was in spectrum1.
 

	
 
	Twitter:
 
	* Added Twitter support using Twitter backend. Thanks to Sarang and
 
	  Google Summer of Code.
 

	
 
	Skype:
 
	* Log more errors.
 

	
 
	Libyahoo2:
 
	* Added new Yahoo backend based on libyahoo2.
 

	
 
	Swiften:
 
	* Added new XMPP backend based on Swiften library.
 

	
 
	Backend API:
 
	* Added Python NetworkPlugin class, so it is now easier to write backends
 
	  in Python (Thanks to Sarang).
README.win32
Show inline comments
 
new file 100644
 
Prerequisites
 
=============
 
 
1. Microsoft Visual C++ 2010 Express or higher edition (http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express)
 
2. Git for Windows (http://code.google.com/p/msysgit/downloads/list)
 
3. CMake 2.8 or newer (http://www.cmake.org/cmake/resources/software.html)
 
 
Libraries
 
=========
 
3. Swiften library and Python for run scons (http://swift.im/git/swift)
 
4. Boost 1.48 or newer (http://sourceforge.net/projects/boost/files/boost/1.49.0/)
 
5. Google ProtoBuf library (http://code.google.com/p/protobuf/downloads/list)
 
 
 
Environment
 
===========
 
 
To create spectrum build environment do:
 
 
0. Create directory where we'll install all dependencies, e.g. C:\env-msvc-x64.
 
Create C:\env-msvc-x64\bin and add it to %PATH%.
 
Assuming you have git, python and cmake in %PATH%, 
 
launch "Visual Studio 2010 command prompt" or
 
"Visual Studio 2010(x64) command prompt", depends on your target (Windows x86 or Windows x86_64).
 
1. unpack and build boost libraries:
 
 
	bootstrap.bat
 
	b2.exe --without-mpi --without-python
 
	b2.exe --without-mpi --without-python install --prefix=C:\env-msvc-x64 release
 
 
2. clone swift repository and build it. Don't forget to point it to our env directory:
 
 
	git clone git://swift.im/swift
 
	cd swift
 
	echo boost_includedir="c:/env-msvc-x64/include/boost-1_49" > config.py
 
	echo boost_libdir="c:/env-msvc-x64/lib" >> config.py 
 
	scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 force_configure=1
 
	scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 C:\env-msvc-x64
 
 
TODO: fix in upstream
 
You may need manually copy compiled 3rdParty libs to C:\env-msvc-x64\lib\3rdParty\Expat, 
 
C:\env-msvc-x64\lib\3rdParty\LibIDN, C:\env-msvc-x64\lib\3rdParty\Zlib
 
 
3. unpack and compile protobuf as described in its documentation. 
 
 
Run extract_includes.bat in vsprojects/ directory and move resulting vsprojects/include/google/ directory to our C:\env-msvc-x64\include
 
 
Move protoc.exe to C:\env-msvc-x64\bin\ and libprotobuf.lib to C:\env-msvc-x64\lib
 
 
4. Install gtkmm
 
 
Download installer from https://live.gnome.org/gtkmm/MSWindows and install gtkmm into C:\env-msvc-x64\
 
 
5. Install libpurple headers
 
 
Download http://www.pidgin.im/download/source/ , extract it and copy libpurple directory in C:\env-msvc-x64\include
 
 
6. You're ready! :) Clone libtransport into C:\env-msvc-x64\libtransport (You *must* clone it into this directory, because libtransport will try to find the dependencies in ../lib and ../include)
 
 
Compile it as:
 
 
	set CMAKE_INCLUDE_PATH=C:\env-msvc-x64\include
 
	cmake . -G "NMake Makefiles" -DBOOST_INCLUDEDIR=../include/boost-1_49 -DBOOST_LIBRARYDIR=../lib -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=C:\env-msvc-x64 -DGIT_EXECUTABLE="c:\Program Files (x86)\git\bin\git.exe"
 
	nmake
 
 
TODO: libpurple_backend compilation
 
\ No newline at end of file
backends/CMakeLists.txt
Show inline comments
 
if (PROTOBUF_FOUND)
 
	if ( PURPLE_LIBRARY AND PURPLE_INCLUDE_DIR )
 
	if (PURPLE_FOUND)
 
		ADD_SUBDIRECTORY(libpurple)
 
	endif()
 

	
 
@@ -7,12 +7,18 @@ if (PROTOBUF_FOUND)
 
		ADD_SUBDIRECTORY(libcommuni)
 
	endif()
 

	
 
	ADD_SUBDIRECTORY(smstools3)
 
	ADD_SUBDIRECTORY(swiften)
 

	
 
	ADD_SUBDIRECTORY(template)
 

	
 

	
 
if (NOT WIN32)
 
	ADD_SUBDIRECTORY(smstools3)
 
	ADD_SUBDIRECTORY(frotz)
 
# 	if(YAHOO2_FOUND)
 
		ADD_SUBDIRECTORY(libyahoo2)
 
# 	endif()
 
	ADD_SUBDIRECTORY(twitter)
 
	if (${LIBDBUSGLIB_FOUND})
 
		ADD_SUBDIRECTORY(skype)
 
	endif()
backends/frotz/main.cpp
Show inline comments
 
@@ -235,7 +235,11 @@ class FrotzNetworkPlugin : public NetworkPlugin {
 
			directory_iterator end_itr;
 
			for (directory_iterator itr(p); itr != end_itr; ++itr) {
 
				if (extension(itr->path()) == ".z5") {
 
#if BOOST_FILESYSTEM_VERSION == 3
 
					games.push_back(itr->path().filename().string());
 
#else
 
					games.push_back(itr->path().leaf());
 
#endif
 
				}
 
			}
 
			return games;
 
@@ -335,54 +339,19 @@ int main (int argc, char* argv[]) {
 
		return -1;
 
	}
 

	
 
	boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
 
	desc.add_options()
 
		("host,h", value<std::string>(&host), "host")
 
		("port,p", value<int>(&port), "port")
 
		;
 
	try
 
	{
 
		boost::program_options::variables_map vm;
 
		boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
 
		boost::program_options::notify(vm);
 
	}
 
	catch (std::runtime_error& e)
 
	{
 
		std::cout << desc << "\n";
 
		exit(1);
 
	}
 
	catch (...)
 
	{
 
		std::cout << desc << "\n";
 
		exit(1);
 
	}
 

	
 

	
 
	if (argc < 5) {
 
		return 1;
 
	}
 

	
 
// 	QStringList channels;
 
// 	for (int i = 3; i < argc; ++i)
 
// 	{
 
// 		channels.append(argv[i]);
 
// 	}
 
// 
 
// 	MyIrcSession session;
 
// 	session.setNick(argv[2]);
 
// 	session.setAutoJoinChannels(channels);
 
// 	session.connectToServer(argv[1], 6667);
 

	
 
	Config config;
 
	if (!config.load(argv[5])) {
 
		std::cerr << "Can't open " << argv[1] << " configuration file.\n";
 
	std::string error;
 
	Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
 
	if (cfg == NULL) {
 
		std::cerr << error;
 
		return 1;
 
	}
 

	
 
	Swift::SimpleEventLoop eventLoop;
 
	loop_ = &eventLoop;
 
	np = new FrotzNetworkPlugin(&config, &eventLoop, host, port);
 
	np = new FrotzNetworkPlugin(cfg, &eventLoop, host, port);
 
	loop_->run();
 

	
 
	delete cfg;
 

	
 
	return 0;
 
}
backends/libcommuni/main.cpp
Show inline comments
 
@@ -27,62 +27,24 @@ int main (int argc, char* argv[]) {
 
	std::string host;
 
	int port;
 

	
 

	
 
	boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
 
	desc.add_options()
 
		("host,h", value<std::string>(&host), "host")
 
		("port,p", value<int>(&port), "port")
 
		;
 
	try
 
	{
 
		boost::program_options::variables_map vm;
 
		boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
 
		boost::program_options::notify(vm);
 
	}
 
	catch (std::runtime_error& e)
 
	{
 
		std::cout << desc << "\n";
 
		exit(1);
 
	}
 
	catch (...)
 
	{
 
		std::cout << desc << "\n";
 
		exit(1);
 
	}
 

	
 

	
 
	if (argc < 5) {
 
		qDebug("Usage: %s <config>", argv[0]);
 
	std::string error;
 
	Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
 
	if (cfg == NULL) {
 
		std::cerr << error;
 
		return 1;
 
	}
 

	
 
// 	QStringList channels;
 
// 	for (int i = 3; i < argc; ++i)
 
// 	{
 
// 		channels.append(argv[i]);
 
// 	}
 
// 
 
// 	MyIrcSession session;
 
// 	session.setNick(argv[2]);
 
// 	session.setAutoJoinChannels(channels);
 
// 	session.connectToServer(argv[1], 6667);
 

	
 
	Config config;
 
	if (!config.load(argv[5])) {
 
		std::cerr << "Can't open " << argv[1] << " configuration file.\n";
 
		return 1;
 
	}
 
	QCoreApplication app(argc, argv);
 

	
 
	Logging::initBackendLogging(&config);
 
	Logging::initBackendLogging(cfg);
 

	
 
	Swift::QtEventLoop eventLoop;
 

	
 
	if (config.getUnregistered().find("service.irc_server") == config.getUnregistered().end()) {
 
		np = new IRCNetworkPlugin(&config, &eventLoop, host, port);
 
	if (!CONFIG_HAS_KEY(cfg, "service.irc_server")) {
 
		np = new IRCNetworkPlugin(cfg, &eventLoop, host, port);
 
	}
 
	else {
 
		np = new SingleIRCNetworkPlugin(&config, &eventLoop, host, port);
 
		np = new SingleIRCNetworkPlugin(cfg, &eventLoop, host, port);
 
	}
 

	
 
	return app.exec();
backends/libcommuni/session.cpp
Show inline comments
 
@@ -142,6 +142,13 @@ void MyIrcSession::on_topicChanged(IrcMessage *message) {
 

	
 
void MyIrcSession::on_messageReceived(IrcMessage *message) {
 
	IrcPrivateMessage *m = (IrcPrivateMessage *) message;
 
	if (m->isRequest()) {
 
		QString request = m->message().split(" ", QString::SkipEmptyParts).value(0).toUpper();
 
		if (request == "PING" || request == "TIME" || request == "VERSION") {
 
			LOG4CXX_INFO(logger, user << ": " << TO_UTF8(request) << " received and has been answered");
 
			return;
 
		}
 
	}
 

	
 
	std::string target = TO_UTF8(m->target());
 
	LOG4CXX_INFO(logger, user << ": Message from " << target);
backends/libcommuni/singleircnetworkplugin.cpp
Show inline comments
 
@@ -10,13 +10,19 @@ DEFINE_LOGGER(logger, "SingleIRCNetworkPlugin");
 

	
 
SingleIRCNetworkPlugin::SingleIRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
 
	this->config = config;
 
	m_server = config->getUnregistered().find("service.irc_server")->second;
 
	if (CONFIG_HAS_KEY(config, "service.irc_server")) {
 
		m_server = CONFIG_STRING(config, "service.irc_server");
 
	}
 
	else {
 
		LOG4CXX_ERROR(logger, "No [service] irc_server defined, exiting...");
 
		exit(-1);
 
	}
 
	m_socket = new QTcpSocket();
 
	m_socket->connectToHost(FROM_UTF8(host), port);
 
	connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
 

	
 
	if (config->getUnregistered().find("service.irc_identify") != config->getUnregistered().end()) {
 
		m_identify = config->getUnregistered().find("service.irc_identify")->second;
 
	if (CONFIG_HAS_KEY(config, "service.irc_identify")) {
 
		m_identify = CONFIG_STRING(config, "service.irc_identify");
 
	}
 
	else {
 
		m_identify = "NickServ identify $name $password";
 
@@ -52,6 +58,7 @@ void SingleIRCNetworkPlugin::handleLoginRequest(const std::string &user, const s
 
	session->setRealName(FROM_UTF8(legacyName));
 
	session->setHost(FROM_UTF8(m_server));
 
	session->setPort(6667);
 
	session->setEncoding( "utf-8" );
 

	
 
	if (!password.empty()) {
 
		std::string identify = m_identify;
backends/libpurple/CMakeLists.txt
Show inline comments
 
@@ -3,10 +3,14 @@ FILE(GLOB SRC *.cpp)
 
 
ADD_EXECUTABLE(spectrum2_libpurple_backend ${SRC})
 
 
if(NOT WIN32)
 
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
 
if(CMAKE_COMPILER_IS_GNUCXX)
 
	if (NOT WIN32)
 
	target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
 
	else()
 
	target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
 
	endif()
 
else()
 
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
 
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin ${PROTOBUF_LIBRARY})
 
endif()
 
 
INSTALL(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin)
backends/libpurple/gen_dynamic_purple.py
Show inline comments
 
@@ -132,7 +132,7 @@ def output():
 

	
 
	header = open("purple_defs.h", "w")
 
	print >> header, "#pragma once"
 
	print >> header, "#ifdef WIN32"
 
	print >> header, "#if PURPLE_RUNTIME"
 

	
 
	print >> header, """
 
#include <Windows.h>
 
@@ -186,7 +186,7 @@ def output():
 
	cpp = open("purple_defs.cpp", "w")
 
	print >> cpp, "#include \"purple_defs.h\""
 
	print >> cpp, ""
 
	print >> cpp, "#ifdef WIN32"
 
	print >> cpp, "#if PURPLE_RUNTIME"
 
	print >> cpp, "static HMODULE f_hPurple = NULL;"
 
	for d in definitions:
 
		#purple_util_set_user_wrapped_fnc purple_util_set_user_wrapped = NULL;
 
@@ -195,8 +195,8 @@ def output():
 
	print >> cpp, "#endif"
 

	
 
	print >> cpp, "bool resolvePurpleFunctions() {"
 
	print >> cpp, "#ifdef WIN32"
 
	print >> cpp, "\tf_hPurple = LoadLibrary(\"libpurple.dll\");"
 
	print >> cpp, "#if PURPLE_RUNTIME"
 
	print >> cpp, "\tf_hPurple = LoadLibrary(L\"libpurple.dll\");"
 
	print >> cpp, "\tif (!f_hPurple)"
 
	print >> cpp, "\t\t\treturn false;"
 
	for d in definitions:
backends/libpurple/geventloop.cpp
Show inline comments
 
@@ -98,7 +98,7 @@ static guint input_add(gint fd,
 
	}
 

	
 
#ifdef WIN32
 
	channel = wpurple_g_io_channel_win32_new_socket(fd);
 
	channel = wpurple_g_io_channel_win32_new_socket_wrapped(fd);
 
#else
 
	channel = g_io_channel_unix_new(fd);
 
#endif
backends/libpurple/main.cpp
Show inline comments
 
#include "utils.h"
 

	
 
#include "glib.h"
 

	
 
// win32/libc_interface.h defines its own socket(), read() and so on.
 
// We don't want to use it here.
 
#define _LIBC_INTERFACE_H_ 1
 

	
 
#include "purple.h"
 
#include <algorithm>
 
#include <iostream>
 
@@ -15,6 +20,7 @@
 
#include "malloc.h"
 
#include <algorithm>
 
#include "errno.h"
 
#include <boost/make_shared.hpp>
 

	
 
#ifdef WITH_LIBEVENT
 
#include <event.h>
 
@@ -22,6 +28,7 @@
 

	
 
#ifdef WIN32
 
#include "win32/win32dep.h"
 
#define close closesocket
 
#define ssize_t SSIZE_T
 
#include <process.h>
 
#define getpid _getpid
 
@@ -69,48 +76,10 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 

	
 
class SpectrumNetworkPlugin;
 

	
 
GKeyFile *keyfile;
 
boost::shared_ptr<Config> config;
 
SpectrumNetworkPlugin *np;
 

	
 
static std::string replaceAll(
 
  std::string result,
 
  const std::string& replaceWhat,
 
  const std::string& replaceWithWhat)
 
{
 
  while(1)
 
  {
 
	const int pos = result.find(replaceWhat);
 
	if (pos==-1) break;
 
	result.replace(pos,replaceWhat.size(),replaceWithWhat);
 
  }
 
  return result;
 
}
 

	
 
static std::string KEYFILE_STRING(const std::string &cat, const std::string &key, const std::string &def = "") {
 
	gchar *str = g_key_file_get_string(keyfile, cat.c_str(), key.c_str(), 0);
 
	if (!str) {
 
		return def;
 
	}
 
	std::string ret(str);
 
	g_free(str);
 

	
 
	if (ret.find("#") != std::string::npos) {
 
		ret = ret.substr(0, ret.find("#"));
 
		while(*(ret.end() - 1) == ' ') {
 
			ret.erase(ret.end() - 1);
 
		}
 
	}
 

	
 
	if (ret.find("$jid") != std::string::npos) {
 
		std::string jid = KEYFILE_STRING("service", "jid");
 
		ret = replaceAll(ret, "$jid", jid);
 
	}
 
	return ret;
 
}
 

	
 
#define KEYFILE_BOOL(CAT, KEY) g_key_file_get_boolean(keyfile, CAT, KEY, 0)
 

	
 
static gchar *host = NULL;
 
static std::string host;
 
static int port = 10000;
 

	
 
struct FTData {
 
@@ -119,19 +88,13 @@ struct FTData {
 
	bool paused;
 
};
 

	
 
static GOptionEntry options_entries[] = {
 
	{ "host", 'h', 0, G_OPTION_ARG_STRING, &host, "Host to connect to", NULL },
 
	{ "port", 'p', 0, G_OPTION_ARG_INT, &port, "Port to connect to", NULL },
 
	{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL }
 
};
 

	
 
static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info);
 

	
 
static gboolean ft_ui_ready(void *data) {
 
	PurpleXfer *xfer = (PurpleXfer *) data;
 
	FTData *ftdata = (FTData *) xfer->ui_data;
 
	ftdata->timer = 0;
 
	purple_xfer_ui_ready((PurpleXfer *) data);
 
	purple_xfer_ui_ready_wrapped((PurpleXfer *) data);
 
	return FALSE;
 
}
 

	
 
@@ -209,11 +172,11 @@ static std::string getAlias(PurpleBuddy *m_buddy) {
 
	if (contact && contact->alias) {
 
		alias = contact->alias;
 
	}
 
	else if (purple_buddy_get_alias(m_buddy)) {
 
		alias = (std::string) purple_buddy_get_alias(m_buddy);
 
	else if (purple_buddy_get_alias_wrapped(m_buddy)) {
 
		alias = (std::string) purple_buddy_get_alias_wrapped(m_buddy);
 
	}
 
	else {
 
		alias = (std::string) purple_buddy_get_server_alias(m_buddy);
 
		alias = (std::string) purple_buddy_get_server_alias_wrapped(m_buddy);
 
	}
 
	return alias;
 
}
 
@@ -231,7 +194,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 

	
 
		void getProtocolAndName(const std::string &legacyName, std::string &name, std::string &protocol) {
 
			name = legacyName;
 
			protocol = KEYFILE_STRING("service", "protocol");
 
			protocol = CONFIG_STRING(config, "service.protocol");
 
			if (protocol == "any") {
 
				protocol = name.substr(0, name.find("."));
 
				name = name.substr(name.find(".") + 1);
 
@@ -242,55 +205,58 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			char* contents;
 
			gsize length;
 
			gboolean ret = false;
 
			if (!KEYFILE_STRING("backend", "avatars_directory").empty()) {
 
				std::string f = KEYFILE_STRING("backend", "avatars_directory") + "/" + legacyName;
 
			if (!CONFIG_STRING(config, "backend.avatars_directory").empty()) {
 
				std::string f = CONFIG_STRING(config, "backend.avatars_directory") + "/" + legacyName;
 
				ret = g_file_get_contents (f.c_str(), &contents, &length, NULL);
 
			}
 

	
 
			if (!KEYFILE_STRING("backend", "default_avatar").empty() && !ret) {
 
				ret = g_file_get_contents (KEYFILE_STRING("backend", "default_avatar").c_str(),
 
			if (!CONFIG_STRING(config, "backend.default_avatar").empty() && !ret) {
 
				ret = g_file_get_contents (CONFIG_STRING(config, "backend.default_avatar").c_str(),
 
											&contents, &length, NULL);
 
			}
 

	
 
			if (ret) {
 
				purple_buddy_icons_set_account_icon(account, (guchar *) contents, length);
 
				purple_buddy_icons_set_account_icon_wrapped(account, (guchar *) contents, length);
 
			}
 
		}
 

	
 
		void setDefaultAccountOptions(PurpleAccount *account) {
 
			int i = 0;
 
			gchar **keys = g_key_file_get_keys (keyfile, "purple", NULL, NULL);
 
			while (keys && keys[i] != NULL) {
 
				std::string key = keys[i];
 
			Config::SectionValuesCont purpleConfigValues = config->getSectionValues("purple");
 

	
 
				if (key == "fb_api_key" || key == "fb_api_secret") {
 
					purple_account_set_bool(account, "auth_fb", TRUE);
 
				}
 
			BOOST_FOREACH ( const Config::SectionValuesCont::value_type & keyItem, purpleConfigValues )
 
			{
 
				std::string key = keyItem.first;
 
				std::string strippedKey = boost::erase_first_copy(key, "purple.");
 

	
 
				if (strippedKey == "fb_api_key" || strippedKey == "fb_api_secret") {
 
					purple_account_set_bool_wrapped(account, "auth_fb", TRUE);
 
 				}
 

	
 
				PurplePlugin *plugin = purple_find_prpl(purple_account_get_protocol_id(account));
 
				PurplePlugin *plugin = purple_find_prpl_wrapped(purple_account_get_protocol_id_wrapped(account));
 
				PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
 
				bool found = false;
 
				for (GList *l = prpl_info->protocol_options; l != NULL; l = l->next) {
 
					PurpleAccountOption *option = (PurpleAccountOption *) l->data;
 
					PurplePrefType type = purple_account_option_get_type(option);
 
					std::string key2(purple_account_option_get_setting(option));
 
					if (key != key2) {
 
					PurplePrefType type = purple_account_option_get_type_wrapped(option);
 
					std::string key2(purple_account_option_get_setting_wrapped(option));
 
					if (strippedKey != key2) {
 
						continue;
 
					}
 
					
 
					found = true;
 
					switch (type) {
 
						case PURPLE_PREF_BOOLEAN:
 
							purple_account_set_bool(account, key.c_str(), fromString<bool>(KEYFILE_STRING("purple", key)));
 
							purple_account_set_bool_wrapped(account, strippedKey.c_str(), fromString<bool>(keyItem.second.as<std::string>()));
 
							break;
 

	
 
						case PURPLE_PREF_INT:
 
							purple_account_set_int(account, key.c_str(), fromString<int>(KEYFILE_STRING("purple", key)));
 
							purple_account_set_int_wrapped(account, strippedKey.c_str(), fromString<int>(keyItem.second.as<std::string>()));
 
							break;
 

	
 
						case PURPLE_PREF_STRING:
 
						case PURPLE_PREF_STRING_LIST:
 
							purple_account_set_string(account, key.c_str(), KEYFILE_STRING("purple", key).c_str());
 
							purple_account_set_string_wrapped(account, strippedKey.c_str(), keyItem.second.as<std::string>().c_str());
 
							break;
 
						default:
 
							continue;
 
@@ -299,27 +265,26 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				}
 

	
 
				if (!found) {
 
					purple_account_set_string(account, key.c_str(), KEYFILE_STRING("purple", key).c_str());
 
					purple_account_set_string_wrapped(account, strippedKey.c_str(), keyItem.second.as<std::string>().c_str());
 
				}
 
				i++;
 
			}
 
			g_strfreev (keys);
 

	
 
			char* contents;
 
			gsize length;
 
			gboolean ret = g_file_get_contents ("gfire.cfg", &contents, &length, NULL);
 
			if (ret) {
 
				purple_account_set_int(account, "version", fromString<int>(std::string(contents, length)));
 
				purple_account_set_int_wrapped(account, "version", fromString<int>(std::string(contents, length)));
 
			}
 

	
 

	
 
			if (KEYFILE_STRING("service", "protocol") == "prpl-novell") {
 
				std::string username(purple_account_get_username(account));
 
			if (CONFIG_STRING(config, "service.protocol") == "prpl-novell") {
 
				std::string username(purple_account_get_username_wrapped(account));
 
				std::vector <std::string> u = split(username, '@');
 
				purple_account_set_username(account, (const char*) u.front().c_str());
 
				purple_account_set_username_wrapped(account, (const char*) u.front().c_str());
 
				std::vector <std::string> s = split(u.back(), ':'); 
 
				purple_account_set_string(account, "server", s.front().c_str());
 
				purple_account_set_int(account, "port", atoi(s.back().c_str()));  
 
				purple_account_set_string_wrapped(account, "server", s.front().c_str());
 
				purple_account_set_int_wrapped(account, "port", atoi(s.back().c_str()));  
 
			}
 

	
 
		}
 
@@ -337,20 +302,25 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				return;
 
			}
 

	
 
			if (!purple_find_prpl(protocol.c_str())) {
 
			if (!purple_find_prpl_wrapped(protocol.c_str())) {
 
				LOG4CXX_INFO(logger,  name.c_str() << ": Invalid protocol '" << protocol << "'");
 
				np->handleDisconnected(user, 0, "Invalid protocol " + protocol);
 
				return;
 
			}
 

	
 
			if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL) {
 
			if (purple_accounts_find_wrapped(name.c_str(), protocol.c_str()) != NULL) {
 
				account = purple_accounts_find_wrapped(name.c_str(), protocol.c_str());
 
				if (m_accounts.find(account) != m_accounts.end() && m_accounts[account] != user) {
 
					LOG4CXX_INFO(logger, "Account '" << name << "' is already used by '" << m_accounts[account] << "'");
 
					np->handleDisconnected(user, 0, "Account '" + name + "' is already used by '" + m_accounts[account] + "'");
 
					return;
 
				}
 
				LOG4CXX_INFO(logger, "Using previously created account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
 
				account = purple_accounts_find(name.c_str(), protocol.c_str());
 
			}
 
			else {
 
				LOG4CXX_INFO(logger, "Creating account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
 
				account = purple_account_new(name.c_str(), protocol.c_str());
 
				purple_accounts_add(account);
 
				account = purple_account_new_wrapped(name.c_str(), protocol.c_str());
 
				purple_accounts_add_wrapped(account);
 
			}
 

	
 
			m_sessions[user] = account;
 
@@ -359,42 +329,40 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			// Default avatar
 
			setDefaultAvatar(account, legacyName);
 

	
 
			purple_account_set_password(account, password.c_str());
 
			purple_account_set_bool(account, "custom_smileys", FALSE);
 
			purple_account_set_bool(account, "direct_connect", FALSE);
 
			purple_account_set_password_wrapped(account, password.c_str());
 
			purple_account_set_bool_wrapped(account, "custom_smileys", FALSE);
 
			purple_account_set_bool_wrapped(account, "direct_connect", FALSE);
 

	
 
			setDefaultAccountOptions(account);
 

	
 
			// Enable account + privacy lists
 
			purple_account_set_enabled(account, "spectrum", TRUE);
 
			if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
 
				purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
 
			purple_account_set_enabled_wrapped(account, "spectrum", TRUE);
 
			if (CONFIG_BOOL(config, "service.enable_privacy_lists")) {
 
				purple_account_set_privacy_type_wrapped(account, PURPLE_PRIVACY_DENY_USERS);
 
			}
 

	
 
			// Set the status
 
			const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE);
 
			const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive_wrapped(account, PURPLE_STATUS_AVAILABLE);
 
			if (status_type != NULL) {
 
				purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
 
				purple_account_set_status_wrapped(account, purple_status_type_get_id_wrapped(status_type), TRUE, NULL);
 
			}
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				if (purple_account_get_int(account, "version", 0) != 0) {
 
					std::string data = stringOf(purple_account_get_int(account, "version", 0));
 
				if (purple_account_get_int_wrapped(account, "version", 0) != 0) {
 
					std::string data = stringOf(purple_account_get_int_wrapped(account, "version", 0));
 
					g_file_set_contents ("gfire.cfg", data.c_str(), data.size(), NULL);
 
				}
 
// 				VALGRIND_DO_LEAK_CHECK;
 
				m_sessions.erase(user);
 
				purple_account_disconnect(account);
 
				purple_account_set_enabled(account, "spectrum", FALSE);
 
				purple_account_disconnect_wrapped(account);
 
				purple_account_set_enabled_wrapped(account, "spectrum", FALSE);
 

	
 
				g_free(account->ui_data);
 
				account->ui_data = NULL;
 
				m_accounts.erase(account);
 

	
 
				purple_accounts_delete(account);
 
				purple_accounts_delete_wrapped(account);
 
#ifndef WIN32
 
				malloc_trim(0);
 
#endif
 
@@ -409,7 +377,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				switch(status) {
 
					case pbnetwork::STATUS_AWAY: {
 
						st = PURPLE_STATUS_AWAY;
 
						if (!purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AWAY))
 
						if (!purple_account_get_status_type_with_primitive_wrapped(account, PURPLE_STATUS_AWAY))
 
							st = PURPLE_STATUS_EXTENDED_AWAY;
 
						else
 
							st = PURPLE_STATUS_AWAY;
 
@@ -420,7 +388,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
						break;
 
					}
 
					case pbnetwork::STATUS_XA: {
 
						if (!purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_EXTENDED_AWAY))
 
						if (!purple_account_get_status_type_with_primitive_wrapped(account, PURPLE_STATUS_EXTENDED_AWAY))
 
							st = PURPLE_STATUS_AWAY;
 
						else
 
							st = PURPLE_STATUS_EXTENDED_AWAY;
 
@@ -437,19 +405,19 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
						st = PURPLE_STATUS_AVAILABLE;
 
						break;
 
				}
 
				gchar *_markup = purple_markup_escape_text(statusMessage.c_str(), -1);
 
				gchar *_markup = purple_markup_escape_text_wrapped(statusMessage.c_str(), -1);
 
				std::string markup(_markup);
 
				g_free(_markup);
 

	
 
				// we are already connected so we have to change status
 
				const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, (PurpleStatusPrimitive) st);
 
				const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive_wrapped(account, (PurpleStatusPrimitive) st);
 
				if (status_type != NULL) {
 
					// send presence to legacy network
 
					if (!markup.empty()) {
 
						purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, "message", markup.c_str(), NULL);
 
						purple_account_set_status_wrapped(account, purple_status_type_get_id_wrapped(status_type), TRUE, "message", markup.c_str(), NULL);
 
					}
 
					else {
 
						purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
 
						purple_account_set_status_wrapped(account, purple_status_type_get_id_wrapped(status_type), TRUE, NULL);
 
					}
 
				}
 
			}
 
@@ -458,29 +426,29 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, legacyName.c_str(), account);
 
				PurpleConversation *conv = purple_find_conversation_with_account_wrapped(PURPLE_CONV_TYPE_CHAT, legacyName.c_str(), account);
 
				if (!conv) {
 
					conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account);
 
					conv = purple_find_conversation_with_account_wrapped(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account);
 
					if (!conv) {
 
						conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str());
 
						conv = purple_conversation_new_wrapped(PURPLE_CONV_TYPE_IM, account, legacyName.c_str());
 
					}
 
				}
 
				if (xhtml.empty()) {
 
					gchar *_markup = purple_markup_escape_text(message.c_str(), -1);
 
					if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
 
						purple_conv_im_send(PURPLE_CONV_IM(conv), _markup);
 
					gchar *_markup = purple_markup_escape_text_wrapped(message.c_str(), -1);
 
					if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
 
						purple_conv_im_send_wrapped(PURPLE_CONV_IM_WRAPPED(conv), _markup);
 
					}
 
					else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 
						purple_conv_chat_send(PURPLE_CONV_CHAT(conv), _markup);
 
					else if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_CHAT) {
 
						purple_conv_chat_send_wrapped(PURPLE_CONV_CHAT_WRAPPED(conv), _markup);
 
					}
 
					g_free(_markup);
 
				}
 
				else {
 
					if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
 
						purple_conv_im_send(PURPLE_CONV_IM(conv), xhtml.c_str());
 
					if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
 
						purple_conv_im_send_wrapped(PURPLE_CONV_IM_WRAPPED(conv), xhtml.c_str());
 
					}
 
					else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 
						purple_conv_chat_send(PURPLE_CONV_CHAT(conv), xhtml.c_str());
 
					else if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_CHAT) {
 
						purple_conv_chat_send_wrapped(PURPLE_CONV_CHAT_WRAPPED(conv), xhtml.c_str());
 
					}
 
				}
 
			}
 
@@ -490,18 +458,18 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				std::string name = legacyName;
 
				if (KEYFILE_STRING("service", "protocol") == "any" && legacyName.find("prpl-") == 0) {
 
				if (CONFIG_STRING(config, "service.protocol") == "any" && legacyName.find("prpl-") == 0) {
 
					name = name.substr(name.find(".") + 1);
 
				}
 
				m_vcards[user + name] = id;
 

	
 
				if (KEYFILE_BOOL("backend", "no_vcard_fetch") && name != purple_account_get_username(account)) {
 
					PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
 
					notify_user_info(purple_account_get_connection(account), name.c_str(), user_info);
 
					purple_notify_user_info_destroy(user_info);
 
				if (CONFIG_BOOL(config, "backend.no_vcard_fetch") && name != purple_account_get_username_wrapped(account)) {
 
					PurpleNotifyUserInfo *user_info = purple_notify_user_info_new_wrapped();
 
					notify_user_info(purple_account_get_connection_wrapped(account), name.c_str(), user_info);
 
					purple_notify_user_info_destroy_wrapped(user_info);
 
				}
 
				else {
 
					serv_get_info(purple_account_get_connection(account), name.c_str());
 
					serv_get_info_wrapped(purple_account_get_connection_wrapped(account), name.c_str());
 
				}
 
				
 
			}
 
@@ -510,8 +478,8 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
		void handleVCardUpdatedRequest(const std::string &user, const std::string &image, const std::string &nickname) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				purple_account_set_alias(account, nickname.c_str());
 
				purple_account_set_public_alias(account, nickname.c_str(), NULL, NULL);
 
				purple_account_set_alias_wrapped(account, nickname.c_str());
 
				purple_account_set_public_alias_wrapped(account, nickname.c_str(), NULL, NULL);
 
				gssize size = image.size();
 
				// this will be freed by libpurple
 
				guchar *photo = (guchar *) g_malloc(size * sizeof(guchar));
 
@@ -519,7 +487,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 

	
 
				if (!photo)
 
					return;
 
				purple_buddy_icons_set_account_icon(account, photo, size);
 
				purple_buddy_icons_set_account_icon_wrapped(account, photo, size);
 
			}
 
		}
 

	
 
@@ -530,10 +498,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
					m_authRequests[user + buddyName]->deny_cb(m_authRequests[user + buddyName]->user_data);
 
					m_authRequests.erase(user + buddyName);
 
				}
 
				PurpleBuddy *buddy = purple_find_buddy(account, buddyName.c_str());
 
				PurpleBuddy *buddy = purple_find_buddy_wrapped(account, buddyName.c_str());
 
				if (buddy) {
 
					purple_account_remove_buddy(account, buddy, purple_buddy_get_group(buddy));
 
					purple_blist_remove_buddy(buddy);
 
					purple_account_remove_buddy_wrapped(account, buddy, purple_buddy_get_group_wrapped(buddy));
 
					purple_blist_remove_buddy_wrapped(buddy);
 
				}
 
			}
 
		}
 
@@ -548,43 +516,43 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
					m_authRequests.erase(user + buddyName);
 
				}
 

	
 
				PurpleBuddy *buddy = purple_find_buddy(account, buddyName.c_str());
 
				PurpleBuddy *buddy = purple_find_buddy_wrapped(account, buddyName.c_str());
 
				if (buddy) {
 
					if (getAlias(buddy) != alias) {
 
						purple_blist_alias_buddy(buddy, alias.c_str());
 
						purple_blist_server_alias_buddy(buddy, alias.c_str());
 
						serv_alias_buddy(buddy);
 
						purple_blist_alias_buddy_wrapped(buddy, alias.c_str());
 
						purple_blist_server_alias_buddy_wrapped(buddy, alias.c_str());
 
						serv_alias_buddy_wrapped(buddy);
 
					}
 

	
 
					PurpleGroup *group = purple_find_group(groups.c_str());
 
					PurpleGroup *group = purple_find_group_wrapped(groups.c_str());
 
					if (!group) {
 
						group = purple_group_new(groups.c_str());
 
						group = purple_group_new_wrapped(groups.c_str());
 
					}
 
					purple_blist_add_contact(purple_buddy_get_contact(buddy), group ,NULL);
 
					purple_blist_add_contact_wrapped(purple_buddy_get_contact_wrapped(buddy), group ,NULL);
 
				}
 
				else {
 
					PurpleBuddy *buddy = purple_buddy_new(account, buddyName.c_str(), alias.c_str());
 
					PurpleBuddy *buddy = purple_buddy_new_wrapped(account, buddyName.c_str(), alias.c_str());
 

	
 
					// Add newly created buddy to legacy network roster.
 
					PurpleGroup *group = purple_find_group(groups.c_str());
 
					PurpleGroup *group = purple_find_group_wrapped(groups.c_str());
 
					if (!group) {
 
						group = purple_group_new(groups.c_str());
 
						group = purple_group_new_wrapped(groups.c_str());
 
					}
 
					purple_blist_add_buddy(buddy, NULL, group ,NULL);
 
					purple_account_add_buddy(account, buddy);
 
					purple_blist_add_buddy_wrapped(buddy, NULL, group ,NULL);
 
					purple_account_add_buddy_wrapped(account, buddy);
 
				}
 
			}
 
		}
 

	
 
		void handleBuddyBlockToggled(const std::string &user, const std::string &buddyName, bool blocked) {
 
			if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
 
			if (CONFIG_BOOL(config, "service.enable_privacy_lists")) {
 
				PurpleAccount *account = m_sessions[user];
 
				if (account) {
 
					if (blocked) {
 
						purple_privacy_deny(account, buddyName.c_str(), FALSE, FALSE);
 
						purple_privacy_deny_wrapped(account, buddyName.c_str(), FALSE, FALSE);
 
					}
 
					else {
 
						purple_privacy_allow(account, buddyName.c_str(), FALSE, FALSE);
 
						purple_privacy_allow_wrapped(account, buddyName.c_str(), FALSE, FALSE);
 
					}
 
				}
 
			}
 
@@ -593,28 +561,28 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
		void handleTypingRequest(const std::string &user, const std::string &buddyName) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				serv_send_typing(purple_account_get_connection(account), buddyName.c_str(), PURPLE_TYPING);
 
				serv_send_typing_wrapped(purple_account_get_connection_wrapped(account), buddyName.c_str(), PURPLE_TYPING);
 
			}
 
		}
 

	
 
		void handleTypedRequest(const std::string &user, const std::string &buddyName) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				serv_send_typing(purple_account_get_connection(account), buddyName.c_str(), PURPLE_TYPED);
 
				serv_send_typing_wrapped(purple_account_get_connection_wrapped(account), buddyName.c_str(), PURPLE_TYPED);
 
			}
 
		}
 

	
 
		void handleStoppedTypingRequest(const std::string &user, const std::string &buddyName) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				serv_send_typing(purple_account_get_connection(account), buddyName.c_str(), PURPLE_NOT_TYPING);
 
				serv_send_typing_wrapped(purple_account_get_connection_wrapped(account), buddyName.c_str(), PURPLE_NOT_TYPING);
 
			}
 
		}
 

	
 
		void handleAttentionRequest(const std::string &user, const std::string &buddyName, const std::string &message) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				purple_prpl_send_attention(purple_account_get_connection(account), buddyName.c_str(), 0);
 
				purple_prpl_send_attention_wrapped(purple_account_get_connection_wrapped(account), buddyName.c_str(), 0);
 
			}
 
		}
 

	
 
@@ -624,13 +592,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				return;
 
			}
 

	
 
			PurpleConnection *gc = purple_account_get_connection(account);
 
			PurpleConnection *gc = purple_account_get_connection_wrapped(account);
 
			GHashTable *comps = NULL;
 

	
 
			// Check if the PurpleChat is not stored in buddy list
 
			PurpleChat *chat = purple_blist_find_chat(account, room.c_str());
 
			PurpleChat *chat = purple_blist_find_chat_wrapped(account, room.c_str());
 
			if (chat) {
 
				comps = purple_chat_get_components(chat);
 
				comps = purple_chat_get_components_wrapped(chat);
 
			}
 
			else if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) {
 
				comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, room.c_str());
 
@@ -638,7 +606,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 

	
 
			LOG4CXX_INFO(logger, user << ": Joining the room " << room);
 
			if (comps) {
 
				serv_join_chat(gc, comps);
 
				serv_join_chat_wrapped(gc, comps);
 
				g_hash_table_destroy(comps);
 
			}
 
		}
 
@@ -649,8 +617,8 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				return;
 
			}
 

	
 
			PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, room.c_str(), account);
 
			purple_conversation_destroy(conv);
 
			PurpleConversation *conv = purple_find_conversation_with_account_wrapped(PURPLE_CONV_TYPE_CHAT, room.c_str(), account);
 
			purple_conversation_destroy_wrapped(conv);
 
		}
 

	
 
		void handleFTStartRequest(const std::string &user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) {
 
@@ -661,8 +629,8 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				
 
				ftData->id = ftID;
 
				m_xfers[ftID] = xfer;
 
				purple_xfer_request_accepted(xfer, fileName.c_str());
 
				purple_xfer_ui_ready(xfer);
 
				purple_xfer_request_accepted_wrapped(xfer, fileName.c_str());
 
				purple_xfer_ui_ready_wrapped(xfer);
 
			}
 
		}
 

	
 
@@ -670,7 +638,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			PurpleXfer *xfer = m_unhandledXfers[user + fileName + buddyName];
 
			if (xfer) {
 
				m_unhandledXfers.erase(user + fileName + buddyName);
 
				purple_xfer_request_denied(xfer);
 
				purple_xfer_request_denied_wrapped(xfer);
 
			}
 
		}
 

	
 
@@ -688,7 +656,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				return;
 
			FTData *ftData = (FTData *) xfer->ui_data;
 
			ftData->paused = false;
 
			purple_xfer_ui_ready(xfer);
 
			purple_xfer_ui_ready_wrapped(xfer);
 
		}
 

	
 
		void sendData(const std::string &string) {
 
@@ -698,7 +666,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			write(main_socket, string.c_str(), string.size());
 
#endif
 
			if (writeInput == 0)
 
				writeInput = purple_input_add(main_socket, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
 
				writeInput = purple_input_add_wrapped(main_socket, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
 
		}
 

	
 
		void readyForData() {
 
@@ -710,9 +678,9 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			for (std::vector<PurpleXfer *>::const_iterator it = tmp.begin(); it != tmp.end(); it++) {
 
				FTData *ftData = (FTData *) (*it)->ui_data;
 
				if (ftData->timer == 0) {
 
					ftData->timer = purple_timeout_add(1, ft_ui_ready, *it);
 
					ftData->timer = purple_timeout_add_wrapped(1, ft_ui_ready, *it);
 
				}
 
// 				purple_xfer_ui_ready(xfer);
 
// 				purple_xfer_ui_ready_wrapped(xfer);
 
			}
 
		}
 

	
 
@@ -726,13 +694,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
};
 

	
 
static bool getStatus(PurpleBuddy *m_buddy, pbnetwork::StatusType &status, std::string &statusMessage) {
 
	PurplePresence *pres = purple_buddy_get_presence(m_buddy);
 
	PurplePresence *pres = purple_buddy_get_presence_wrapped(m_buddy);
 
	if (pres == NULL)
 
		return false;
 
	PurpleStatus *stat = purple_presence_get_active_status(pres);
 
	PurpleStatus *stat = purple_presence_get_active_status_wrapped(pres);
 
	if (stat == NULL)
 
		return false;
 
	int st = purple_status_type_get_primitive(purple_status_get_type(stat));
 
	int st = purple_status_type_get_primitive_wrapped(purple_status_get_type_wrapped(stat));
 

	
 
	switch(st) {
 
		case PURPLE_STATUS_AVAILABLE: {
 
@@ -760,10 +728,10 @@ static bool getStatus(PurpleBuddy *m_buddy, pbnetwork::StatusType &status, std::
 
			break;
 
	}
 

	
 
	const char *message = purple_status_get_attr_string(stat, "message");
 
	const char *message = purple_status_get_attr_string_wrapped(stat, "message");
 

	
 
	if (message != NULL) {
 
		char *stripped = purple_markup_strip_html(message);
 
		char *stripped = purple_markup_strip_html_wrapped(message);
 
		statusMessage = std::string(stripped);
 
		g_free(stripped);
 
	}
 
@@ -774,10 +742,10 @@ static bool getStatus(PurpleBuddy *m_buddy, pbnetwork::StatusType &status, std::
 

	
 
static std::string getIconHash(PurpleBuddy *m_buddy) {
 
	char *avatarHash = NULL;
 
	PurpleBuddyIcon *icon = purple_buddy_icons_find(purple_buddy_get_account(m_buddy), purple_buddy_get_name(m_buddy));
 
	PurpleBuddyIcon *icon = purple_buddy_icons_find_wrapped(purple_buddy_get_account_wrapped(m_buddy), purple_buddy_get_name_wrapped(m_buddy));
 
	if (icon) {
 
		avatarHash = purple_buddy_icon_get_full_path(icon);
 
		purple_buddy_icon_unref(icon);
 
		avatarHash = purple_buddy_icon_get_full_path_wrapped(icon);
 
		purple_buddy_icon_unref_wrapped(icon);
 
	}
 

	
 
	if (avatarHash) {
 
@@ -807,14 +775,14 @@ static std::string getIconHash(PurpleBuddy *m_buddy) {
 

	
 
static std::vector<std::string> getGroups(PurpleBuddy *m_buddy) {
 
	std::vector<std::string> groups;
 
	if (purple_buddy_get_name(m_buddy)) {
 
		GSList *buddies = purple_find_buddies(purple_buddy_get_account(m_buddy), purple_buddy_get_name(m_buddy));
 
	if (purple_buddy_get_name_wrapped(m_buddy)) {
 
		GSList *buddies = purple_find_buddies_wrapped(purple_buddy_get_account_wrapped(m_buddy), purple_buddy_get_name_wrapped(m_buddy));
 
		while(buddies) {
 
			PurpleGroup *g = purple_buddy_get_group((PurpleBuddy *) buddies->data);
 
			PurpleGroup *g = purple_buddy_get_group_wrapped((PurpleBuddy *) buddies->data);
 
			buddies = g_slist_delete_link(buddies, buddies);
 

	
 
			if(g && purple_group_get_name(g)) {
 
				groups.push_back(purple_group_get_name(g));
 
			if(g && purple_group_get_name_wrapped(g)) {
 
				groups.push_back(purple_group_get_name_wrapped(g));
 
			}
 
		}
 
	}
 
@@ -827,13 +795,13 @@ static std::vector<std::string> getGroups(PurpleBuddy *m_buddy) {
 
}
 

	
 
static void buddyListNewNode(PurpleBlistNode *node) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(node))
 
		return;
 
	PurpleBuddy *buddy = (PurpleBuddy *) node;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	PurpleAccount *account = purple_buddy_get_account_wrapped(buddy);
 

	
 
	std::vector<std::string> groups = getGroups(buddy);
 
	LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy) << " group (" << groups.size() << ")=" << groups[0]);
 
	LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name_wrapped(buddy) << " " << getAlias(buddy) << " group (" << groups.size() << ")=" << groups[0]);
 

	
 
	// Status
 
	pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
 
@@ -841,22 +809,22 @@ static void buddyListNewNode(PurpleBlistNode *node) {
 
	getStatus(buddy, status, message);
 

	
 
	// Tooltip
 
	PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account));
 
	PurplePlugin *prpl = purple_find_prpl_wrapped(purple_account_get_protocol_id_wrapped(account));
 
	PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 

	
 
	bool blocked = false;
 
	if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
 
	if (CONFIG_BOOL(config, "service.enable_privacy_lists")) {
 
		if (prpl_info && prpl_info->tooltip_text) {
 
			PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
 
			PurpleNotifyUserInfo *user_info = purple_notify_user_info_new_wrapped();
 
			prpl_info->tooltip_text(buddy, user_info, true);
 
			GList *entries = purple_notify_user_info_get_entries(user_info);
 
			GList *entries = purple_notify_user_info_get_entries_wrapped(user_info);
 

	
 
			while (entries) {
 
				PurpleNotifyUserInfoEntry *entry = (PurpleNotifyUserInfoEntry *)(entries->data);
 
				if (purple_notify_user_info_entry_get_label(entry) && purple_notify_user_info_entry_get_value(entry)) {
 
					std::string label = purple_notify_user_info_entry_get_label(entry);
 
				if (purple_notify_user_info_entry_get_label_wrapped(entry) && purple_notify_user_info_entry_get_value_wrapped(entry)) {
 
					std::string label = purple_notify_user_info_entry_get_label_wrapped(entry);
 
					if (label == "Blocked" ) {
 
						if (std::string(purple_notify_user_info_entry_get_value(entry)) == "Yes") {
 
						if (std::string(purple_notify_user_info_entry_get_value_wrapped(entry)) == "Yes") {
 
							blocked = true;
 
							break;
 
						}
 
@@ -864,39 +832,39 @@ static void buddyListNewNode(PurpleBlistNode *node) {
 
				}
 
				entries = entries->next;
 
			}
 
			purple_notify_user_info_destroy(user_info);
 
			purple_notify_user_info_destroy_wrapped(user_info);
 
		}
 

	
 
		if (!blocked) {
 
			blocked = purple_privacy_check(account, purple_buddy_get_name(buddy)) == false;
 
			blocked = purple_privacy_check_wrapped(account, purple_buddy_get_name_wrapped(buddy)) == false;
 
		}
 
		else {
 
			bool purpleBlocked = purple_privacy_check(account, purple_buddy_get_name(buddy)) == false;
 
			bool purpleBlocked = purple_privacy_check_wrapped(account, purple_buddy_get_name_wrapped(buddy)) == false;
 
			if (blocked != purpleBlocked) {
 
				purple_privacy_deny(account, purple_buddy_get_name(buddy), FALSE, FALSE);
 
				purple_privacy_deny_wrapped(account, purple_buddy_get_name_wrapped(buddy), FALSE, FALSE);
 
			}
 
		}
 
	}
 

	
 
	np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy), status, message, getIconHash(buddy),
 
	np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name_wrapped(buddy), getAlias(buddy), getGroups(buddy), status, message, getIconHash(buddy),
 
		blocked
 
	);
 
}
 

	
 
static void buddyListUpdate(PurpleBuddyList *list, PurpleBlistNode *node) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(node))
 
		return;
 
	buddyListNewNode(node);
 
}
 

	
 
static void buddyPrivacyChanged(PurpleBlistNode *node, void *data) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(node))
 
		return;
 
	buddyListUpdate(NULL, node);
 
}
 

	
 
static void NodeRemoved(PurpleBlistNode *node, void *data) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(node))
 
		return;
 
// 	PurpleBuddy *buddy = (PurpleBuddy *) node;
 
}
 
@@ -921,24 +889,24 @@ static PurpleBlistUiOps blistUiOps =
 

	
 
static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime) {
 
	// Don't forwards our own messages.
 
	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM && (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)) {
 
	if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM && (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)) {
 
		return;
 
	}
 
	PurpleAccount *account = purple_conversation_get_account(conv);
 
	PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
 

	
 
// 	char *striped = purple_markup_strip_html(message);
 
// 	char *striped = purple_markup_strip_html_wrapped(message);
 
// 	std::string msg = striped;
 
// 	g_free(striped);
 

	
 
	std::string w = purple_normalize(account, who);
 
	std::string w = purple_normalize_wrapped(account, who);
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
		w.erase((int) pos, w.length() - (int) pos);
 

	
 
	// Escape HTML characters.
 
	char *newline = purple_strdup_withhtml(msg);
 
	char *newline = purple_strdup_withhtml_wrapped(msg);
 
	char *strip, *xhtml;
 
	purple_markup_html_to_xhtml(newline, &xhtml, &strip);
 
	purple_markup_html_to_xhtml_wrapped(newline, &xhtml, &strip);
 
// 	xhtml_linkified = spectrum_markup_linkify(xhtml);
 
	std::string message_(strip);
 

	
 
@@ -962,17 +930,17 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
 

	
 
// 	LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "'");
 

	
 
	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
 
	if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
 
		np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_);
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name(conv) << "' " << w);
 
		np->handleMessage(np->m_accounts[account], purple_conversation_get_name(conv), message_, w, xhtml_);
 
		LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name_wrapped(conv) << "' " << w);
 
		np->handleMessage(np->m_accounts[account], purple_conversation_get_name_wrapped(conv), message_, w, xhtml_);
 
	}
 
}
 

	
 
static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) {
 
	PurpleAccount *account = purple_conversation_get_account(conv);
 
	PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
 

	
 
	GList *l = cbuddies;
 
	while (l != NULL) {
 
@@ -995,19 +963,19 @@ static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gbool
 
// 			item->addAttribute("role", "participant");
 
		}
 

	
 
		np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name(conv), (int) flags, pbnetwork::STATUS_ONLINE);
 
		np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name_wrapped(conv), (int) flags, pbnetwork::STATUS_ONLINE);
 

	
 
		l = l->next;
 
	}
 
}
 

	
 
static void conv_chat_remove_users(PurpleConversation *conv, GList *users) {
 
	PurpleAccount *account = purple_conversation_get_account(conv);
 
	PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
 

	
 
	GList *l = users;
 
	while (l != NULL) {
 
		std::string name((char *) l->data);
 
		np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name(conv), 0, pbnetwork::STATUS_NONE);
 
		np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name_wrapped(conv), 0, pbnetwork::STATUS_NONE);
 

	
 
		l = l->next;
 
	}
 
@@ -1043,11 +1011,11 @@ struct Dis {
 

	
 
static gboolean disconnectMe(void *data) {
 
	Dis *d = (Dis *) data;
 
	PurpleAccount *account = purple_accounts_find(d->name.c_str(), d->protocol.c_str());
 
	PurpleAccount *account = purple_accounts_find_wrapped(d->name.c_str(), d->protocol.c_str());
 
	delete d;
 

	
 
	if (account) {
 
		np->handleLogoutRequest(np->m_accounts[account], purple_account_get_username(account));
 
		np->handleLogoutRequest(np->m_accounts[account], purple_account_get_username_wrapped(account));
 
	}
 
	return FALSE;
 
}
 
@@ -1058,12 +1026,12 @@ static gboolean pingTimeout(void *data) {
 
}
 

	
 
static void connection_report_disconnect(PurpleConnection *gc, PurpleConnectionError reason, const char *text){
 
	PurpleAccount *account = purple_connection_get_account(gc);
 
	PurpleAccount *account = purple_connection_get_account_wrapped(gc);
 
	np->handleDisconnected(np->m_accounts[account], (int) reason, text ? text : "");
 
	Dis *d = new Dis;
 
	d->name = purple_account_get_username(account);
 
	d->protocol = purple_account_get_protocol_id(account);
 
	purple_timeout_add_seconds(10, disconnectMe, d);
 
// 	Dis *d = new Dis;
 
// 	d->name = purple_account_get_username_wrapped(account);
 
// 	d->protocol = purple_account_get_protocol_id_wrapped(account);
 
// 	purple_timeout_add_seconds_wrapped(10, disconnectMe, d);
 
}
 

	
 
static PurpleConnectionUiOps conn_ui_ops =
 
@@ -1082,8 +1050,8 @@ static PurpleConnectionUiOps conn_ui_ops =
 
};
 

	
 
static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info) {
 
	PurpleAccount *account = purple_connection_get_account(gc);
 
	std::string name(purple_normalize(account, who));
 
	PurpleAccount *account = purple_connection_get_account_wrapped(gc);
 
	std::string name(purple_normalize_wrapped(account, who));
 
	std::transform(name.begin(), name.end(), name.begin(), ::tolower);
 

	
 
	size_t pos = name.find("/");
 
@@ -1091,7 +1059,7 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif
 
		name.erase((int) pos, name.length() - (int) pos);
 

	
 
	
 
	GList *vcardEntries = purple_notify_user_info_get_entries(user_info);
 
	GList *vcardEntries = purple_notify_user_info_get_entries_wrapped(user_info);
 
	PurpleNotifyUserInfoEntry *vcardEntry;
 
	std::string firstName;
 
	std::string lastName;
 
@@ -1103,22 +1071,22 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif
 

	
 
	while (vcardEntries) {
 
		vcardEntry = (PurpleNotifyUserInfoEntry *)(vcardEntries->data);
 
		if (purple_notify_user_info_entry_get_label(vcardEntry) && purple_notify_user_info_entry_get_value(vcardEntry)){
 
			label = purple_notify_user_info_entry_get_label(vcardEntry);
 
		if (purple_notify_user_info_entry_get_label_wrapped(vcardEntry) && purple_notify_user_info_entry_get_value_wrapped(vcardEntry)){
 
			label = purple_notify_user_info_entry_get_label_wrapped(vcardEntry);
 
			if (label == "Given Name" || label == "First Name") {
 
				firstName = purple_notify_user_info_entry_get_value(vcardEntry);
 
				firstName = purple_notify_user_info_entry_get_value_wrapped(vcardEntry);
 
			}
 
			else if (label == "Family Name" || label == "Last Name") {
 
				lastName = purple_notify_user_info_entry_get_value(vcardEntry);
 
				lastName = purple_notify_user_info_entry_get_value_wrapped(vcardEntry);
 
			}
 
			else if (label=="Nickname" || label == "Nick") {
 
				nickname = purple_notify_user_info_entry_get_value(vcardEntry);
 
				nickname = purple_notify_user_info_entry_get_value_wrapped(vcardEntry);
 
			}
 
			else if (label=="Full Name") {
 
				fullName = purple_notify_user_info_entry_get_value(vcardEntry);
 
				fullName = purple_notify_user_info_entry_get_value_wrapped(vcardEntry);
 
			}
 
			else {
 
				LOG4CXX_WARN(logger, "Unhandled VCard Label '" << purple_notify_user_info_entry_get_label(vcardEntry) << "' " << purple_notify_user_info_entry_get_value(vcardEntry));
 
				LOG4CXX_WARN(logger, "Unhandled VCard Label '" << purple_notify_user_info_entry_get_label_wrapped(vcardEntry) << "' " << purple_notify_user_info_entry_get_value_wrapped(vcardEntry));
 
			}
 
		}
 
		vcardEntries = vcardEntries->next;
 
@@ -1131,12 +1099,12 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif
 
		nickname = fullName;
 
	}
 

	
 
	bool ownInfo = name == purple_account_get_username(account);
 
	bool ownInfo = name == purple_account_get_username_wrapped(account);
 

	
 
	if (ownInfo) {
 
		const gchar *displayname = purple_connection_get_display_name(gc);
 
		const gchar *displayname = purple_connection_get_display_name_wrapped(gc);
 
		if (!displayname) {
 
			displayname = purple_account_get_name_for_display(account);
 
			displayname = purple_account_get_name_for_display_wrapped(account);
 
		}
 

	
 
		if (displayname && nickname.empty()) {
 
@@ -1144,26 +1112,26 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif
 
		}
 

	
 
		// avatar
 
		PurpleStoredImage *avatar = purple_buddy_icons_find_account_icon(account);
 
		PurpleStoredImage *avatar = purple_buddy_icons_find_account_icon_wrapped(account);
 
		if (avatar) {
 
			const gchar * data = (const gchar *) purple_imgstore_get_data(avatar);
 
			size_t len = purple_imgstore_get_size(avatar);
 
			const gchar * data = (const gchar *) purple_imgstore_get_data_wrapped(avatar);
 
			size_t len = purple_imgstore_get_size_wrapped(avatar);
 
			if (len < 300000 && data) {
 
				photo = std::string(data, len);
 
			}
 
			purple_imgstore_unref(avatar);
 
			purple_imgstore_unref_wrapped(avatar);
 
		}
 
	}
 

	
 
	PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(gc), who);
 
	PurpleBuddy *buddy = purple_find_buddy_wrapped(purple_connection_get_account_wrapped(gc), who);
 
	if (buddy && photo.size() == 0) {
 
		gsize len;
 
		PurpleBuddyIcon *icon = NULL;
 
		icon = purple_buddy_icons_find(purple_connection_get_account(gc), name.c_str());
 
		icon = purple_buddy_icons_find_wrapped(purple_connection_get_account_wrapped(gc), name.c_str());
 
		if (icon) {
 
			if (true) {
 
				gchar *data;
 
				gchar *path = purple_buddy_icon_get_full_path(icon);
 
				gchar *path = purple_buddy_icon_get_full_path_wrapped(icon);
 
				if (path) {
 
					if (g_file_get_contents(path, &data, &len, NULL)) {
 
						photo = std::string(data, len);
 
@@ -1173,12 +1141,12 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif
 
				}
 
			}
 
			else {
 
				const gchar * data = (gchar*)purple_buddy_icon_get_data(icon, &len);
 
				const gchar * data = (gchar*)purple_buddy_icon_get_data_wrapped(icon, &len);
 
				if (len < 300000 && data) {
 
					photo = std::string(data, len);
 
				}
 
			}
 
			purple_buddy_icon_unref(icon);
 
			purple_buddy_icon_unref_wrapped(icon);
 
		}
 
	}
 

	
 
@@ -1259,7 +1227,7 @@ static void XferCreated(PurpleXfer *xfer) {
 
		return;
 
	}
 

	
 
// 	PurpleAccount *account = purple_xfer_get_account(xfer);
 
// 	PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
 
// 	np->handleFTStart(np->m_accounts[account], xfer->who, xfer, "", xhtml_);
 
}
 

	
 
@@ -1267,7 +1235,7 @@ static void XferDestroyed(PurpleXfer *xfer) {
 
	std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
 
	FTData *ftdata = (FTData *) xfer->ui_data;
 
	if (ftdata && ftdata->timer) {
 
		purple_timeout_remove(ftdata->timer);
 
		purple_timeout_remove_wrapped(ftdata->timer);
 
	}
 
	if (ftdata) {
 
		np->m_xfers.erase(ftdata->id);
 
@@ -1275,8 +1243,8 @@ static void XferDestroyed(PurpleXfer *xfer) {
 
}
 

	
 
static void xferCanceled(PurpleXfer *xfer) {
 
	PurpleAccount *account = purple_xfer_get_account(xfer);
 
	std::string filename(xfer ? purple_xfer_get_filename(xfer) : "");
 
	PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
 
	std::string filename(xfer ? purple_xfer_get_filename_wrapped(xfer) : "");
 
	std::string w = xfer->who;
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
@@ -1284,12 +1252,12 @@ static void xferCanceled(PurpleXfer *xfer) {
 

	
 
	FTData *ftdata = (FTData *) xfer->ui_data;
 

	
 
	np->handleFTFinish(np->m_accounts[account], w, filename, purple_xfer_get_size(xfer), ftdata ? ftdata->id : 0);
 
	np->handleFTFinish(np->m_accounts[account], w, filename, purple_xfer_get_size_wrapped(xfer), ftdata ? ftdata->id : 0);
 
	std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
 
	if (ftdata && ftdata->timer) {
 
		purple_timeout_remove(ftdata->timer);
 
		purple_timeout_remove_wrapped(ftdata->timer);
 
	}
 
	purple_xfer_unref(xfer);
 
	purple_xfer_unref_wrapped(xfer);
 
}
 

	
 
static void fileSendStart(PurpleXfer *xfer) {
 
@@ -1302,14 +1270,14 @@ static void fileRecvStart(PurpleXfer *xfer) {
 
// 	repeater->fileRecvStart();
 
	FTData *ftData = (FTData *) xfer->ui_data;
 
	if (ftData->timer == 0) {
 
		ftData->timer = purple_timeout_add(1, ft_ui_ready, xfer);
 
		ftData->timer = purple_timeout_add_wrapped(1, ft_ui_ready, xfer);
 
	}
 
}
 

	
 
static void newXfer(PurpleXfer *xfer) {
 
	PurpleAccount *account = purple_xfer_get_account(xfer);
 
	std::string filename(xfer ? purple_xfer_get_filename(xfer) : "");
 
	purple_xfer_ref(xfer);
 
	PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
 
	std::string filename(xfer ? purple_xfer_get_filename_wrapped(xfer) : "");
 
	purple_xfer_ref_wrapped(xfer);
 
	std::string w = xfer->who;
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
@@ -1323,7 +1291,7 @@ static void newXfer(PurpleXfer *xfer) {
 

	
 
	np->m_unhandledXfers[np->m_accounts[account] + filename + w] = xfer;
 

	
 
	np->handleFTStart(np->m_accounts[account], w, filename, purple_xfer_get_size(xfer));
 
	np->handleFTStart(np->m_accounts[account], w, filename, purple_xfer_get_size_wrapped(xfer));
 
}
 

	
 
static void XferReceiveComplete(PurpleXfer *xfer) {
 
@@ -1333,9 +1301,9 @@ static void XferReceiveComplete(PurpleXfer *xfer) {
 
	std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
 
	FTData *ftdata = (FTData *) xfer->ui_data;
 
	if (ftdata && ftdata->timer) {
 
		purple_timeout_remove(ftdata->timer);
 
		purple_timeout_remove_wrapped(ftdata->timer);
 
	}
 
	purple_xfer_unref(xfer);
 
	purple_xfer_unref_wrapped(xfer);
 
}
 

	
 
static void XferSendComplete(PurpleXfer *xfer) {
 
@@ -1344,9 +1312,9 @@ static void XferSendComplete(PurpleXfer *xfer) {
 
	std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
 
	FTData *ftdata = (FTData *) xfer->ui_data;
 
	if (ftdata && ftdata->timer) {
 
		purple_timeout_remove(ftdata->timer);
 
		purple_timeout_remove_wrapped(ftdata->timer);
 
	}
 
	purple_xfer_unref(xfer);
 
	purple_xfer_unref_wrapped(xfer);
 
}
 

	
 
static gssize XferWrite(PurpleXfer *xfer, const guchar *buffer, gssize size) {
 
@@ -1392,15 +1360,15 @@ static PurpleXferUiOps xferUiOps =
 

	
 
static void transport_core_ui_init(void)
 
{
 
	purple_blist_set_ui_ops(&blistUiOps);
 
	purple_accounts_set_ui_ops(&accountUiOps);
 
	purple_notify_set_ui_ops(&notifyUiOps);
 
	purple_request_set_ui_ops(&requestUiOps);
 
	purple_xfers_set_ui_ops(&xferUiOps);
 
	purple_connections_set_ui_ops(&conn_ui_ops);
 
	purple_conversations_set_ui_ops(&conversation_ui_ops);
 
	purple_blist_set_ui_ops_wrapped(&blistUiOps);
 
	purple_accounts_set_ui_ops_wrapped(&accountUiOps);
 
	purple_notify_set_ui_ops_wrapped(&notifyUiOps);
 
	purple_request_set_ui_ops_wrapped(&requestUiOps);
 
	purple_xfers_set_ui_ops_wrapped(&xferUiOps);
 
	purple_connections_set_ui_ops_wrapped(&conn_ui_ops);
 
	purple_conversations_set_ui_ops_wrapped(&conversation_ui_ops);
 
// #ifndef WIN32
 
// 	purple_dnsquery_set_ui_ops(getDNSUiOps());
 
// 	purple_dnsquery_set_ui_ops_wrapped(getDNSUiOps());
 
// #endif
 
}
 

	
 
@@ -1433,10 +1401,10 @@ spectrum_glib_log_handler(const gchar *domain,
 
	}
 

	
 
	if (message != NULL)
 
		new_msg = purple_utf8_try_convert(message);
 
		new_msg = purple_utf8_try_convert_wrapped(message);
 

	
 
	if (domain != NULL)
 
		new_domain = purple_utf8_try_convert(domain);
 
		new_domain = purple_utf8_try_convert_wrapped(domain);
 

	
 
	if (new_msg != NULL) {
 
		std::string area("glib");
 
@@ -1487,7 +1455,7 @@ static PurpleCoreUiOps coreUiOps =
 
};
 

	
 
static void signed_on(PurpleConnection *gc, gpointer unused) {
 
	PurpleAccount *account = purple_connection_get_account(gc);
 
	PurpleAccount *account = purple_connection_get_account_wrapped(gc);
 
	np->handleConnected(np->m_accounts[account]);
 
#ifndef WIN32
 
	// force returning of memory chunks allocated by libxml2 to kernel
 
@@ -1526,7 +1494,7 @@ static PurpleDebugUiOps debugUiOps =
 
};
 

	
 
static void buddyTyping(PurpleAccount *account, const char *who, gpointer null) {
 
	std::string w = purple_normalize(account, who);
 
	std::string w = purple_normalize_wrapped(account, who);
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
		w.erase((int) pos, w.length() - (int) pos);
 
@@ -1534,7 +1502,7 @@ static void buddyTyping(PurpleAccount *account, const char *who, gpointer null)
 
}
 

	
 
static void buddyTyped(PurpleAccount *account, const char *who, gpointer null) {
 
	std::string w = purple_normalize(account, who);
 
	std::string w = purple_normalize_wrapped(account, who);
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
		w.erase((int) pos, w.length() - (int) pos);
 
@@ -1542,7 +1510,7 @@ static void buddyTyped(PurpleAccount *account, const char *who, gpointer null) {
 
}
 

	
 
static void buddyTypingStopped(PurpleAccount *account, const char *who, gpointer null){
 
	std::string w = purple_normalize(account, who);
 
	std::string w = purple_normalize_wrapped(account, who);
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
		w.erase((int) pos, w.length() - (int) pos);
 
@@ -1550,7 +1518,7 @@ static void buddyTypingStopped(PurpleAccount *account, const char *who, gpointer
 
}
 

	
 
static void gotAttention(PurpleAccount *account, const char *who, PurpleConversation *conv, guint type) {
 
	std::string w = purple_normalize(account, who);
 
	std::string w = purple_normalize_wrapped(account, who);
 
	size_t pos = w.find("/");
 
	if (pos != std::string::npos)
 
		w.erase((int) pos, w.length() - (int) pos);
 
@@ -1560,76 +1528,87 @@ static void gotAttention(PurpleAccount *account, const char *who, PurpleConversa
 
static bool initPurple() {
 
	bool ret;
 

	
 
	if (!resolvePurpleFunctions()) {
 
	std::string libPurpleDllPath = CONFIG_STRING_DEFAULTED(config, "purple.libpurple_dll_path", "");
 

	
 
	if (!resolvePurpleFunctions(libPurpleDllPath)) {
 
		LOG4CXX_ERROR(logger, "Unable to load libpurple.dll or some of the needed methods");
 
		return false;
 
	}
 

	
 
	purple_plugins_add_search_path("./plugins");
 
	std::string pluginsDir = CONFIG_STRING_DEFAULTED(config, "purple.plugins_dir", "./plugins");
 
	LOG4CXX_INFO(logger, "Setting libpurple plugins directory to: " << pluginsDir);
 
	purple_plugins_add_search_path_wrapped(pluginsDir.c_str());
 

	
 
	purple_util_set_user_dir("./");
 
	std::string cacertsDir = CONFIG_STRING_DEFAULTED(config, "purple.cacerts_dir", "./ca-certs");
 
	LOG4CXX_INFO(logger, "Setting libpurple cacerts directory to: " << cacertsDir);
 
	purple_certificate_add_ca_search_path_wrapped(cacertsDir.c_str());
 
 
 
	std::string userDir = CONFIG_STRING_DEFAULTED(config, "service.working_dir", "./");
 
	LOG4CXX_INFO(logger, "Setting libpurple user directory to: " << userDir);
 

	
 
	purple_util_set_user_dir_wrapped(userDir.c_str());
 
	remove("./accounts.xml");
 
	remove("./blist.xml");
 

	
 
	purple_debug_set_ui_ops(&debugUiOps);
 
	purple_debug_set_verbose(true);
 
	purple_debug_set_ui_ops_wrapped(&debugUiOps);
 
	purple_debug_set_verbose_wrapped(true);
 

	
 
	purple_core_set_ui_ops(&coreUiOps);
 
	if (KEYFILE_STRING("service", "eventloop") == "libev") {
 
	purple_core_set_ui_ops_wrapped(&coreUiOps);
 
	if (CONFIG_STRING_DEFAULTED(config, "service.eventloop", "") == "libev") {
 
		LOG4CXX_INFO(logger, "Will use libev based event loop");
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, "Will use glib based event loop");
 
	}
 
	purple_eventloop_set_ui_ops(getEventLoopUiOps(KEYFILE_STRING("service", "eventloop") == "libev"));
 
	purple_eventloop_set_ui_ops_wrapped(getEventLoopUiOps(CONFIG_STRING_DEFAULTED(config, "service.eventloop", "") == "libev"));
 

	
 
	ret = purple_core_init("spectrum");
 
	ret = purple_core_init_wrapped("spectrum");
 
	if (ret) {
 
		static int blist_handle;
 
		static int conversation_handle;
 

	
 
		purple_set_blist(purple_blist_new());
 
		purple_blist_load();
 
		purple_set_blist_wrapped(purple_blist_new_wrapped());
 
		purple_blist_load_wrapped();
 

	
 
		purple_prefs_load();
 
		purple_prefs_load_wrapped();
 

	
 
		/* Good default preferences */
 
		/* The combination of these two settings mean that libpurple will never
 
		 * (of its own accord) set all the user accounts idle.
 
		 */
 
		purple_prefs_set_bool("/purple/away/away_when_idle", false);
 
		purple_prefs_set_bool_wrapped("/purple/away/away_when_idle", false);
 
		/*
 
		 * This must be set to something not "none" for idle reporting to work
 
		 * for, e.g., the OSCAR prpl. We don't implement the UI ops, so this is
 
		 * okay for now.
 
		 */
 
		purple_prefs_set_string("/purple/away/idle_reporting", "system");
 
		purple_prefs_set_string_wrapped("/purple/away/idle_reporting", "system");
 

	
 
		/* Disable all logging */
 
		purple_prefs_set_bool("/purple/logging/log_ims", false);
 
		purple_prefs_set_bool("/purple/logging/log_chats", false);
 
		purple_prefs_set_bool("/purple/logging/log_system", false);
 

	
 

	
 
// 		purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", &conversation_handle, PURPLE_CALLBACK(newMessageReceived), NULL);
 
		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL);
 
		purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL);
 
		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-privacy-changed", &conversation_handle, PURPLE_CALLBACK(buddyPrivacyChanged), NULL);
 
		purple_signal_connect(purple_conversations_get_handle(), "got-attention", &conversation_handle, PURPLE_CALLBACK(gotAttention), NULL);
 
		purple_signal_connect(purple_connections_get_handle(), "signed-on", &blist_handle,PURPLE_CALLBACK(signed_on), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL);
 
		purple_prefs_set_bool_wrapped("/purple/logging/log_ims", false);
 
		purple_prefs_set_bool_wrapped("/purple/logging/log_chats", false);
 
		purple_prefs_set_bool_wrapped("/purple/logging/log_system", false);
 

	
 

	
 
// 		purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "received-im-msg", &conversation_handle, PURPLE_CALLBACK(newMessageReceived), NULL);
 
		purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL);
 
		purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL);
 
		purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL);
 
		purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "buddy-privacy-changed", &conversation_handle, PURPLE_CALLBACK(buddyPrivacyChanged), NULL);
 
		purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "got-attention", &conversation_handle, PURPLE_CALLBACK(gotAttention), NULL);
 
		purple_signal_connect_wrapped(purple_connections_get_handle_wrapped(), "signed-on", &blist_handle,PURPLE_CALLBACK(signed_on), NULL);
 
// 		purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL);
 
// 		purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL);
 
// 		purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL);
 
// 		purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL);
 
		purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL);
 
// 		purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL);
 
		static int xfer_handle;
 
		purple_signal_connect(purple_xfers_get_handle(), "file-send-start", &xfer_handle, PURPLE_CALLBACK(fileSendStart), NULL);
 
		purple_signal_connect(purple_xfers_get_handle(), "file-recv-start", &xfer_handle, PURPLE_CALLBACK(fileRecvStart), NULL);
 
		purple_signal_connect(purple_xfers_get_handle(), "file-recv-request", &xfer_handle, PURPLE_CALLBACK(newXfer), NULL);
 
		purple_signal_connect(purple_xfers_get_handle(), "file-recv-complete", &xfer_handle, PURPLE_CALLBACK(XferReceiveComplete), NULL);
 
		purple_signal_connect(purple_xfers_get_handle(), "file-send-complete", &xfer_handle, PURPLE_CALLBACK(XferSendComplete), NULL);
 
		purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-send-start", &xfer_handle, PURPLE_CALLBACK(fileSendStart), NULL);
 
		purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-start", &xfer_handle, PURPLE_CALLBACK(fileRecvStart), NULL);
 
		purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-request", &xfer_handle, PURPLE_CALLBACK(newXfer), NULL);
 
		purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-complete", &xfer_handle, PURPLE_CALLBACK(XferReceiveComplete), NULL);
 
		purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-send-complete", &xfer_handle, PURPLE_CALLBACK(XferSendComplete), NULL);
 
// 
 
// 		purple_commands_init();
 

	
 
@@ -1648,6 +1627,9 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 
		ssize_t n = read(source, ptr, sizeof(buffer));
 
#endif
 
		if (n <= 0) {
 
			if (errno == EAGAIN) {
 
				return;
 
			}
 
			LOG4CXX_INFO(logger, "Diconnecting from spectrum2 server");
 
			exit(errno);
 
		}
 
@@ -1656,7 +1638,7 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 
	}
 
	else {
 
		if (writeInput != 0) {
 
			purple_input_remove(writeInput);
 
			purple_input_remove_wrapped(writeInput);
 
			writeInput = 0;
 
		}
 
		np->readyForData();
 
@@ -1664,82 +1646,55 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 
}
 

	
 
int main(int argc, char **argv) {
 
	GError *error = NULL;
 
	GOptionContext *context;
 
	context = g_option_context_new("config_file_name or profile name");
 
	g_option_context_add_main_entries(context, options_entries, "");
 
	if (!g_option_context_parse (context, &argc, &argv, &error)) {
 
		std::cerr << "option parsing failed: " << error->message << "\n";
 
		return -1;
 
	}
 

	
 
	if (argc != 2) {
 
#ifdef WIN32
 
		std::cout << "Usage: spectrum.exe <configuration_file.cfg>\n";
 
#else
 

	
 
#if GLIB_CHECK_VERSION(2,14,0)
 
	std::cout << g_option_context_get_help(context, FALSE, NULL);
 
#else
 
	std::cout << "Usage: spectrum <configuration_file.cfg>\n";
 
	std::cout << "See \"man spectrum\" for more info.\n";
 
#endif
 
		
 
#endif
 
	}
 
	else {
 
#ifndef WIN32
 
		mallopt(M_CHECK_ACTION, 2);
 
		mallopt(M_PERTURB, 0xb);
 

	
 
		signal(SIGPIPE, SIG_IGN);
 

	
 
		if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
 
			std::cout << "SIGCHLD handler can't be set\n";
 
			g_option_context_free(context);
 
			return -1;
 
		}
 
#endif
 
		keyfile = g_key_file_new ();
 
		if (!g_key_file_load_from_file (keyfile, argv[1], (GKeyFileFlags) 0, 0)) {
 
			std::cout << "Can't open " << argv[1] << " configuration file.\n";
 
			return 1;
 
		}
 

	
 
		Config config;
 
		if (!config.load(argv[1])) {
 
			std::cerr << "Can't open " << argv[1] << " configuration file.\n";
 
			return 1;
 
		}
 
		Logging::initBackendLogging(&config);
 

	
 
		initPurple();
 

	
 
		main_socket = create_socket(host, port);
 
		purple_input_add(main_socket, PURPLE_INPUT_READ, &transportDataReceived, NULL);
 
		purple_timeout_add_seconds(30, pingTimeout, NULL);
 

	
 
		np = new SpectrumNetworkPlugin();
 
		bool libev = KEYFILE_STRING("service", "eventloop") == "libev";
 
	std::string error;
 
	Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
 
	if (cfg == NULL) {
 
		std::cerr << error;
 
		return 1;
 
	}
 

	
 
		GMainLoop *m_loop;
 
	config = boost::shared_ptr<Config>(cfg);
 
 
 
	Logging::initBackendLogging(config.get());
 
	initPurple();
 
 
 
	main_socket = create_socket(host.c_str(), port);
 
	purple_input_add_wrapped(main_socket, PURPLE_INPUT_READ, &transportDataReceived, NULL);
 
	purple_timeout_add_seconds_wrapped(30, pingTimeout, NULL);
 
 
 
	np = new SpectrumNetworkPlugin();
 
	bool libev = CONFIG_STRING_DEFAULTED(config, "service.eventloop", "") == "libev";
 

	
 
	GMainLoop *m_loop;
 
#ifdef WITH_LIBEVENT
 
		if (!libev) {
 
			m_loop = g_main_loop_new(NULL, FALSE);
 
		}
 
		else {
 
			event_init();
 
		}
 
#endif
 
	if (!libev) {
 
		m_loop = g_main_loop_new(NULL, FALSE);
 

	
 
		if (m_loop) {
 
			g_main_loop_run(m_loop);
 
		}
 
#ifdef WITH_LIBEVENT
 
		else {
 
			event_loop(0);
 
		}
 
	}
 
	else {
 
		event_init();
 
	}
 
#endif
 
	m_loop = g_main_loop_new(NULL, FALSE);
 
	if (m_loop) {
 
		g_main_loop_run(m_loop);
 
	}
 
#ifdef WITH_LIBEVENT
 
	else {
 
		event_loop(0);
 
	}
 
#endif
 

	
 
	g_option_context_free(context);
 
	return 0;
 
}
backends/libpurple/purple_defs.cpp
Show inline comments
 
#include "purple_defs.h"
 
bool resolvePurpleFunctions() {
 
#include "utils.h"
 

	
 
#if PURPLE_RUNTIME
 

	
 
using std::string;
 
using std::wstring;
 

	
 
static HMODULE f_hPurple = NULL;
 
purple_debug_set_ui_ops_wrapped_fnc purple_debug_set_ui_ops_wrapped = NULL;
 
purple_debug_set_verbose_wrapped_fnc purple_debug_set_verbose_wrapped = NULL;
 
purple_request_set_ui_ops_wrapped_fnc purple_request_set_ui_ops_wrapped = NULL;
 
purple_imgstore_get_data_wrapped_fnc purple_imgstore_get_data_wrapped = NULL;
 
purple_imgstore_get_size_wrapped_fnc purple_imgstore_get_size_wrapped = NULL;
 
purple_imgstore_unref_wrapped_fnc purple_imgstore_unref_wrapped = NULL;
 
purple_markup_escape_text_wrapped_fnc purple_markup_escape_text_wrapped = NULL;
 
purple_markup_strip_html_wrapped_fnc purple_markup_strip_html_wrapped = NULL;
 
purple_normalize_wrapped_fnc purple_normalize_wrapped = NULL;
 
purple_strdup_withhtml_wrapped_fnc purple_strdup_withhtml_wrapped = NULL;
 
purple_markup_html_to_xhtml_wrapped_fnc purple_markup_html_to_xhtml_wrapped = NULL;
 
purple_utf8_try_convert_wrapped_fnc purple_utf8_try_convert_wrapped = NULL;
 
purple_util_set_user_dir_wrapped_fnc purple_util_set_user_dir_wrapped = NULL;
 
purple_blist_node_get_type_wrapped_fnc purple_blist_node_get_type_wrapped = NULL;
 
purple_buddy_get_alias_wrapped_fnc purple_buddy_get_alias_wrapped = NULL;
 
purple_buddy_get_server_alias_wrapped_fnc purple_buddy_get_server_alias_wrapped = NULL;
 
purple_find_buddy_wrapped_fnc purple_find_buddy_wrapped = NULL;
 
purple_buddy_get_group_wrapped_fnc purple_buddy_get_group_wrapped = NULL;
 
purple_blist_remove_buddy_wrapped_fnc purple_blist_remove_buddy_wrapped = NULL;
 
purple_blist_alias_buddy_wrapped_fnc purple_blist_alias_buddy_wrapped = NULL;
 
purple_blist_server_alias_buddy_wrapped_fnc purple_blist_server_alias_buddy_wrapped = NULL;
 
purple_find_group_wrapped_fnc purple_find_group_wrapped = NULL;
 
purple_group_new_wrapped_fnc purple_group_new_wrapped = NULL;
 
purple_blist_add_contact_wrapped_fnc purple_blist_add_contact_wrapped = NULL;
 
purple_buddy_get_contact_wrapped_fnc purple_buddy_get_contact_wrapped = NULL;
 
purple_buddy_new_wrapped_fnc purple_buddy_new_wrapped = NULL;
 
purple_blist_add_buddy_wrapped_fnc purple_blist_add_buddy_wrapped = NULL;
 
purple_blist_find_chat_wrapped_fnc purple_blist_find_chat_wrapped = NULL;
 
purple_chat_get_components_wrapped_fnc purple_chat_get_components_wrapped = NULL;
 
purple_buddy_get_presence_wrapped_fnc purple_buddy_get_presence_wrapped = NULL;
 
purple_buddy_get_account_wrapped_fnc purple_buddy_get_account_wrapped = NULL;
 
purple_buddy_get_name_wrapped_fnc purple_buddy_get_name_wrapped = NULL;
 
purple_find_buddies_wrapped_fnc purple_find_buddies_wrapped = NULL;
 
purple_group_get_name_wrapped_fnc purple_group_get_name_wrapped = NULL;
 
purple_blist_set_ui_ops_wrapped_fnc purple_blist_set_ui_ops_wrapped = NULL;
 
purple_set_blist_wrapped_fnc purple_set_blist_wrapped = NULL;
 
purple_blist_new_wrapped_fnc purple_blist_new_wrapped = NULL;
 
purple_blist_load_wrapped_fnc purple_blist_load_wrapped = NULL;
 
purple_blist_get_handle_wrapped_fnc purple_blist_get_handle_wrapped = NULL;
 
purple_xfer_ui_ready_wrapped_fnc purple_xfer_ui_ready_wrapped = NULL;
 
purple_xfer_request_accepted_wrapped_fnc purple_xfer_request_accepted_wrapped = NULL;
 
purple_xfer_request_denied_wrapped_fnc purple_xfer_request_denied_wrapped = NULL;
 
purple_certificate_add_ca_search_path_wrapped_fnc purple_certificate_add_ca_search_path_wrapped = NULL;
 
purple_xfer_get_account_wrapped_fnc purple_xfer_get_account_wrapped = NULL;
 
purple_xfer_get_filename_wrapped_fnc purple_xfer_get_filename_wrapped = NULL;
 
purple_xfer_get_size_wrapped_fnc purple_xfer_get_size_wrapped = NULL;
 
purple_xfer_unref_wrapped_fnc purple_xfer_unref_wrapped = NULL;
 
purple_xfer_ref_wrapped_fnc purple_xfer_ref_wrapped = NULL;
 
purple_xfers_set_ui_ops_wrapped_fnc purple_xfers_set_ui_ops_wrapped = NULL;
 
purple_xfers_get_handle_wrapped_fnc purple_xfers_get_handle_wrapped = NULL;
 
purple_signal_connect_wrapped_fnc purple_signal_connect_wrapped = NULL;
 
purple_prefs_load_wrapped_fnc purple_prefs_load_wrapped = NULL;
 
purple_prefs_set_bool_wrapped_fnc purple_prefs_set_bool_wrapped = NULL;
 
purple_prefs_set_string_wrapped_fnc purple_prefs_set_string_wrapped = NULL;
 
purple_notify_user_info_new_wrapped_fnc purple_notify_user_info_new_wrapped = NULL;
 
purple_notify_user_info_destroy_wrapped_fnc purple_notify_user_info_destroy_wrapped = NULL;
 
purple_notify_user_info_get_entries_wrapped_fnc purple_notify_user_info_get_entries_wrapped = NULL;
 
purple_notify_user_info_entry_get_label_wrapped_fnc purple_notify_user_info_entry_get_label_wrapped = NULL;
 
purple_notify_user_info_entry_get_value_wrapped_fnc purple_notify_user_info_entry_get_value_wrapped = NULL;
 
purple_notify_set_ui_ops_wrapped_fnc purple_notify_set_ui_ops_wrapped = NULL;
 
purple_buddy_icons_set_account_icon_wrapped_fnc purple_buddy_icons_set_account_icon_wrapped = NULL;
 
purple_buddy_icons_find_wrapped_fnc purple_buddy_icons_find_wrapped = NULL;
 
purple_buddy_icon_get_full_path_wrapped_fnc purple_buddy_icon_get_full_path_wrapped = NULL;
 
purple_buddy_icon_unref_wrapped_fnc purple_buddy_icon_unref_wrapped = NULL;
 
purple_buddy_icons_find_account_icon_wrapped_fnc purple_buddy_icons_find_account_icon_wrapped = NULL;
 
purple_buddy_icon_get_data_wrapped_fnc purple_buddy_icon_get_data_wrapped = NULL;
 
purple_account_set_bool_wrapped_fnc purple_account_set_bool_wrapped = NULL;
 
purple_account_get_protocol_id_wrapped_fnc purple_account_get_protocol_id_wrapped = NULL;
 
purple_account_set_int_wrapped_fnc purple_account_set_int_wrapped = NULL;
 
purple_account_set_string_wrapped_fnc purple_account_set_string_wrapped = NULL;
 
purple_account_get_username_wrapped_fnc purple_account_get_username_wrapped = NULL;
 
purple_account_set_username_wrapped_fnc purple_account_set_username_wrapped = NULL;
 
purple_accounts_find_wrapped_fnc purple_accounts_find_wrapped = NULL;
 
purple_account_new_wrapped_fnc purple_account_new_wrapped = NULL;
 
purple_accounts_add_wrapped_fnc purple_accounts_add_wrapped = NULL;
 
purple_account_set_password_wrapped_fnc purple_account_set_password_wrapped = NULL;
 
purple_account_set_enabled_wrapped_fnc purple_account_set_enabled_wrapped = NULL;
 
purple_account_set_privacy_type_wrapped_fnc purple_account_set_privacy_type_wrapped = NULL;
 
purple_account_get_status_type_with_primitive_wrapped_fnc purple_account_get_status_type_with_primitive_wrapped = NULL;
 
purple_account_set_status_wrapped_fnc purple_account_set_status_wrapped = NULL;
 
purple_account_get_int_wrapped_fnc purple_account_get_int_wrapped = NULL;
 
purple_account_disconnect_wrapped_fnc purple_account_disconnect_wrapped = NULL;
 
purple_accounts_delete_wrapped_fnc purple_accounts_delete_wrapped = NULL;
 
purple_account_get_connection_wrapped_fnc purple_account_get_connection_wrapped = NULL;
 
purple_account_set_alias_wrapped_fnc purple_account_set_alias_wrapped = NULL;
 
purple_account_set_public_alias_wrapped_fnc purple_account_set_public_alias_wrapped = NULL;
 
purple_account_remove_buddy_wrapped_fnc purple_account_remove_buddy_wrapped = NULL;
 
purple_account_add_buddy_wrapped_fnc purple_account_add_buddy_wrapped = NULL;
 
purple_account_get_name_for_display_wrapped_fnc purple_account_get_name_for_display_wrapped = NULL;
 
purple_accounts_set_ui_ops_wrapped_fnc purple_accounts_set_ui_ops_wrapped = NULL;
 
purple_status_type_get_id_wrapped_fnc purple_status_type_get_id_wrapped = NULL;
 
purple_presence_get_active_status_wrapped_fnc purple_presence_get_active_status_wrapped = NULL;
 
purple_status_type_get_primitive_wrapped_fnc purple_status_type_get_primitive_wrapped = NULL;
 
purple_status_get_type_wrapped_fnc purple_status_get_type_wrapped = NULL;
 
purple_status_get_attr_string_wrapped_fnc purple_status_get_attr_string_wrapped = NULL;
 
serv_get_info_wrapped_fnc serv_get_info_wrapped = NULL;
 
serv_alias_buddy_wrapped_fnc serv_alias_buddy_wrapped = NULL;
 
serv_send_typing_wrapped_fnc serv_send_typing_wrapped = NULL;
 
serv_join_chat_wrapped_fnc serv_join_chat_wrapped = NULL;
 
purple_dnsquery_set_ui_ops_wrapped_fnc purple_dnsquery_set_ui_ops_wrapped = NULL;
 
purple_conversation_get_im_data_wrapped_fnc purple_conversation_get_im_data_wrapped = NULL;
 
purple_conversation_get_chat_data_wrapped_fnc purple_conversation_get_chat_data_wrapped = NULL;
 
purple_find_conversation_with_account_wrapped_fnc purple_find_conversation_with_account_wrapped = NULL;
 
purple_conversation_new_wrapped_fnc purple_conversation_new_wrapped = NULL;
 
purple_conversation_get_type_wrapped_fnc purple_conversation_get_type_wrapped = NULL;
 
purple_conv_im_send_wrapped_fnc purple_conv_im_send_wrapped = NULL;
 
purple_conv_chat_send_wrapped_fnc purple_conv_chat_send_wrapped = NULL;
 
purple_conversation_destroy_wrapped_fnc purple_conversation_destroy_wrapped = NULL;
 
purple_conversation_get_account_wrapped_fnc purple_conversation_get_account_wrapped = NULL;
 
purple_conversation_get_name_wrapped_fnc purple_conversation_get_name_wrapped = NULL;
 
purple_conversations_set_ui_ops_wrapped_fnc purple_conversations_set_ui_ops_wrapped = NULL;
 
purple_conversations_get_handle_wrapped_fnc purple_conversations_get_handle_wrapped = NULL;
 
purple_plugin_action_free_wrapped_fnc purple_plugin_action_free_wrapped = NULL;
 
purple_plugins_add_search_path_wrapped_fnc purple_plugins_add_search_path_wrapped = NULL;
 
purple_connection_get_state_wrapped_fnc purple_connection_get_state_wrapped = NULL;
 
purple_connection_get_account_wrapped_fnc purple_connection_get_account_wrapped = NULL;
 
purple_connection_get_display_name_wrapped_fnc purple_connection_get_display_name_wrapped = NULL;
 
purple_connections_set_ui_ops_wrapped_fnc purple_connections_set_ui_ops_wrapped = NULL;
 
purple_connections_get_handle_wrapped_fnc purple_connections_get_handle_wrapped = NULL;
 
purple_core_set_ui_ops_wrapped_fnc purple_core_set_ui_ops_wrapped = NULL;
 
purple_core_init_wrapped_fnc purple_core_init_wrapped = NULL;
 
purple_input_add_wrapped_fnc purple_input_add_wrapped = NULL;
 
purple_timeout_add_wrapped_fnc purple_timeout_add_wrapped = NULL;
 
purple_timeout_add_seconds_wrapped_fnc purple_timeout_add_seconds_wrapped = NULL;
 
purple_timeout_remove_wrapped_fnc purple_timeout_remove_wrapped = NULL;
 
purple_eventloop_set_ui_ops_wrapped_fnc purple_eventloop_set_ui_ops_wrapped = NULL;
 
purple_input_remove_wrapped_fnc purple_input_remove_wrapped = NULL;
 
purple_privacy_deny_wrapped_fnc purple_privacy_deny_wrapped = NULL;
 
purple_privacy_allow_wrapped_fnc purple_privacy_allow_wrapped = NULL;
 
purple_privacy_check_wrapped_fnc purple_privacy_check_wrapped = NULL;
 
purple_find_prpl_wrapped_fnc purple_find_prpl_wrapped = NULL;
 
purple_prpl_send_attention_wrapped_fnc purple_prpl_send_attention_wrapped = NULL;
 
purple_account_option_get_type_wrapped_fnc purple_account_option_get_type_wrapped = NULL;
 
purple_account_option_get_setting_wrapped_fnc purple_account_option_get_setting_wrapped = NULL;
 
wpurple_g_io_channel_win32_new_socket_wrapped_fnc wpurple_g_io_channel_win32_new_socket_wrapped = NULL;
 
#endif
 
bool resolvePurpleFunctions(const std::string& libPurpleDllPath) {
 
#if PURPLE_RUNTIME
 
	std::wstring dllPath;
 
	if (!libPurpleDllPath.empty())
 
	{
 
		dllPath = utf8ToUtf16(libPurpleDllPath);
 
	}
 
	else
 
	{
 
		// No path was specified, so try loading libpurple from the current working directory
 
		dllPath = L"libpurple.dll";
 
	}
 
	f_hPurple = LoadLibrary(dllPath.c_str());
 
	if (!f_hPurple)
 
			return false;
 
	purple_debug_set_ui_ops_wrapped = (purple_debug_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_debug_set_ui_ops");
 
	if (!purple_debug_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_debug_set_verbose_wrapped = (purple_debug_set_verbose_wrapped_fnc)GetProcAddress(f_hPurple, "purple_debug_set_verbose");
 
	if (!purple_debug_set_verbose_wrapped)
 
		return false;
 

	
 
	purple_request_set_ui_ops_wrapped = (purple_request_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_request_set_ui_ops");
 
	if (!purple_request_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_imgstore_get_data_wrapped = (purple_imgstore_get_data_wrapped_fnc)GetProcAddress(f_hPurple, "purple_imgstore_get_data");
 
	if (!purple_imgstore_get_data_wrapped)
 
		return false;
 

	
 
	purple_imgstore_get_size_wrapped = (purple_imgstore_get_size_wrapped_fnc)GetProcAddress(f_hPurple, "purple_imgstore_get_size");
 
	if (!purple_imgstore_get_size_wrapped)
 
		return false;
 

	
 
	purple_imgstore_unref_wrapped = (purple_imgstore_unref_wrapped_fnc)GetProcAddress(f_hPurple, "purple_imgstore_unref");
 
	if (!purple_imgstore_unref_wrapped)
 
		return false;
 

	
 
	purple_markup_escape_text_wrapped = (purple_markup_escape_text_wrapped_fnc)GetProcAddress(f_hPurple, "purple_markup_escape_text");
 
	if (!purple_markup_escape_text_wrapped)
 
		return false;
 

	
 
	purple_markup_strip_html_wrapped = (purple_markup_strip_html_wrapped_fnc)GetProcAddress(f_hPurple, "purple_markup_strip_html");
 
	if (!purple_markup_strip_html_wrapped)
 
		return false;
 

	
 
	purple_normalize_wrapped = (purple_normalize_wrapped_fnc)GetProcAddress(f_hPurple, "purple_normalize");
 
	if (!purple_normalize_wrapped)
 
		return false;
 

	
 
	purple_strdup_withhtml_wrapped = (purple_strdup_withhtml_wrapped_fnc)GetProcAddress(f_hPurple, "purple_strdup_withhtml");
 
	if (!purple_strdup_withhtml_wrapped)
 
		return false;
 

	
 
	purple_markup_html_to_xhtml_wrapped = (purple_markup_html_to_xhtml_wrapped_fnc)GetProcAddress(f_hPurple, "purple_markup_html_to_xhtml");
 
	if (!purple_markup_html_to_xhtml_wrapped)
 
		return false;
 

	
 
	purple_utf8_try_convert_wrapped = (purple_utf8_try_convert_wrapped_fnc)GetProcAddress(f_hPurple, "purple_utf8_try_convert");
 
	if (!purple_utf8_try_convert_wrapped)
 
		return false;
 

	
 
	purple_util_set_user_dir_wrapped = (purple_util_set_user_dir_wrapped_fnc)GetProcAddress(f_hPurple, "purple_util_set_user_dir");
 
	if (!purple_util_set_user_dir_wrapped)
 
		return false;
 

	
 
	purple_certificate_add_ca_search_path_wrapped = (purple_util_set_user_dir_wrapped_fnc)GetProcAddress(f_hPurple, "purple_certificate_add_ca_search_path");
 
	if (!purple_certificate_add_ca_search_path_wrapped)
 
		return false;
 

	
 
	purple_blist_node_get_type_wrapped = (purple_blist_node_get_type_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_node_get_type");
 
	if (!purple_blist_node_get_type_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_alias_wrapped = (purple_buddy_get_alias_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_alias");
 
	if (!purple_buddy_get_alias_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_server_alias_wrapped = (purple_buddy_get_server_alias_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_server_alias");
 
	if (!purple_buddy_get_server_alias_wrapped)
 
		return false;
 

	
 
	purple_find_buddy_wrapped = (purple_find_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_find_buddy");
 
	if (!purple_find_buddy_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_group_wrapped = (purple_buddy_get_group_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_group");
 
	if (!purple_buddy_get_group_wrapped)
 
		return false;
 

	
 
	purple_blist_remove_buddy_wrapped = (purple_blist_remove_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_remove_buddy");
 
	if (!purple_blist_remove_buddy_wrapped)
 
		return false;
 

	
 
	purple_blist_alias_buddy_wrapped = (purple_blist_alias_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_alias_buddy");
 
	if (!purple_blist_alias_buddy_wrapped)
 
		return false;
 

	
 
	purple_blist_server_alias_buddy_wrapped = (purple_blist_server_alias_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_server_alias_buddy");
 
	if (!purple_blist_server_alias_buddy_wrapped)
 
		return false;
 

	
 
	purple_find_group_wrapped = (purple_find_group_wrapped_fnc)GetProcAddress(f_hPurple, "purple_find_group");
 
	if (!purple_find_group_wrapped)
 
		return false;
 

	
 
	purple_group_new_wrapped = (purple_group_new_wrapped_fnc)GetProcAddress(f_hPurple, "purple_group_new");
 
	if (!purple_group_new_wrapped)
 
		return false;
 

	
 
	purple_blist_add_contact_wrapped = (purple_blist_add_contact_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_add_contact");
 
	if (!purple_blist_add_contact_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_contact_wrapped = (purple_buddy_get_contact_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_contact");
 
	if (!purple_buddy_get_contact_wrapped)
 
		return false;
 

	
 
	purple_buddy_new_wrapped = (purple_buddy_new_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_new");
 
	if (!purple_buddy_new_wrapped)
 
		return false;
 

	
 
	purple_blist_add_buddy_wrapped = (purple_blist_add_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_add_buddy");
 
	if (!purple_blist_add_buddy_wrapped)
 
		return false;
 

	
 
	purple_blist_find_chat_wrapped = (purple_blist_find_chat_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_find_chat");
 
	if (!purple_blist_find_chat_wrapped)
 
		return false;
 

	
 
	purple_chat_get_components_wrapped = (purple_chat_get_components_wrapped_fnc)GetProcAddress(f_hPurple, "purple_chat_get_components");
 
	if (!purple_chat_get_components_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_presence_wrapped = (purple_buddy_get_presence_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_presence");
 
	if (!purple_buddy_get_presence_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_account_wrapped = (purple_buddy_get_account_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_account");
 
	if (!purple_buddy_get_account_wrapped)
 
		return false;
 

	
 
	purple_buddy_get_name_wrapped = (purple_buddy_get_name_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_get_name");
 
	if (!purple_buddy_get_name_wrapped)
 
		return false;
 

	
 
	purple_find_buddies_wrapped = (purple_find_buddies_wrapped_fnc)GetProcAddress(f_hPurple, "purple_find_buddies");
 
	if (!purple_find_buddies_wrapped)
 
		return false;
 

	
 
	purple_group_get_name_wrapped = (purple_group_get_name_wrapped_fnc)GetProcAddress(f_hPurple, "purple_group_get_name");
 
	if (!purple_group_get_name_wrapped)
 
		return false;
 

	
 
	purple_blist_set_ui_ops_wrapped = (purple_blist_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_set_ui_ops");
 
	if (!purple_blist_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_set_blist_wrapped = (purple_set_blist_wrapped_fnc)GetProcAddress(f_hPurple, "purple_set_blist");
 
	if (!purple_set_blist_wrapped)
 
		return false;
 

	
 
	purple_blist_new_wrapped = (purple_blist_new_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_new");
 
	if (!purple_blist_new_wrapped)
 
		return false;
 

	
 
	purple_blist_load_wrapped = (purple_blist_load_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_load");
 
	if (!purple_blist_load_wrapped)
 
		return false;
 

	
 
	purple_blist_get_handle_wrapped = (purple_blist_get_handle_wrapped_fnc)GetProcAddress(f_hPurple, "purple_blist_get_handle");
 
	if (!purple_blist_get_handle_wrapped)
 
		return false;
 

	
 
	purple_xfer_ui_ready_wrapped = (purple_xfer_ui_ready_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_ui_ready");
 
	if (!purple_xfer_ui_ready_wrapped)
 
		return false;
 

	
 
	purple_xfer_request_accepted_wrapped = (purple_xfer_request_accepted_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_request_accepted");
 
	if (!purple_xfer_request_accepted_wrapped)
 
		return false;
 

	
 
	purple_xfer_request_denied_wrapped = (purple_xfer_request_denied_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_request_denied");
 
	if (!purple_xfer_request_denied_wrapped)
 
		return false;
 

	
 
	purple_xfer_get_account_wrapped = (purple_xfer_get_account_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_get_account");
 
	if (!purple_xfer_get_account_wrapped)
 
		return false;
 

	
 
	purple_xfer_get_filename_wrapped = (purple_xfer_get_filename_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_get_filename");
 
	if (!purple_xfer_get_filename_wrapped)
 
		return false;
 

	
 
	purple_xfer_get_size_wrapped = (purple_xfer_get_size_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_get_size");
 
	if (!purple_xfer_get_size_wrapped)
 
		return false;
 

	
 
	purple_xfer_unref_wrapped = (purple_xfer_unref_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_unref");
 
	if (!purple_xfer_unref_wrapped)
 
		return false;
 

	
 
	purple_xfer_ref_wrapped = (purple_xfer_ref_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfer_ref");
 
	if (!purple_xfer_ref_wrapped)
 
		return false;
 

	
 
	purple_xfers_set_ui_ops_wrapped = (purple_xfers_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfers_set_ui_ops");
 
	if (!purple_xfers_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_xfers_get_handle_wrapped = (purple_xfers_get_handle_wrapped_fnc)GetProcAddress(f_hPurple, "purple_xfers_get_handle");
 
	if (!purple_xfers_get_handle_wrapped)
 
		return false;
 

	
 
	purple_signal_connect_wrapped = (purple_signal_connect_wrapped_fnc)GetProcAddress(f_hPurple, "purple_signal_connect");
 
	if (!purple_signal_connect_wrapped)
 
		return false;
 

	
 
	purple_prefs_load_wrapped = (purple_prefs_load_wrapped_fnc)GetProcAddress(f_hPurple, "purple_prefs_load");
 
	if (!purple_prefs_load_wrapped)
 
		return false;
 

	
 
	purple_prefs_set_bool_wrapped = (purple_prefs_set_bool_wrapped_fnc)GetProcAddress(f_hPurple, "purple_prefs_set_bool");
 
	if (!purple_prefs_set_bool_wrapped)
 
		return false;
 

	
 
	purple_prefs_set_string_wrapped = (purple_prefs_set_string_wrapped_fnc)GetProcAddress(f_hPurple, "purple_prefs_set_string");
 
	if (!purple_prefs_set_string_wrapped)
 
		return false;
 

	
 
	purple_notify_user_info_new_wrapped = (purple_notify_user_info_new_wrapped_fnc)GetProcAddress(f_hPurple, "purple_notify_user_info_new");
 
	if (!purple_notify_user_info_new_wrapped)
 
		return false;
 

	
 
	purple_notify_user_info_destroy_wrapped = (purple_notify_user_info_destroy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_notify_user_info_destroy");
 
	if (!purple_notify_user_info_destroy_wrapped)
 
		return false;
 

	
 
	purple_notify_user_info_get_entries_wrapped = (purple_notify_user_info_get_entries_wrapped_fnc)GetProcAddress(f_hPurple, "purple_notify_user_info_get_entries");
 
	if (!purple_notify_user_info_get_entries_wrapped)
 
		return false;
 

	
 
	purple_notify_user_info_entry_get_label_wrapped = (purple_notify_user_info_entry_get_label_wrapped_fnc)GetProcAddress(f_hPurple, "purple_notify_user_info_entry_get_label");
 
	if (!purple_notify_user_info_entry_get_label_wrapped)
 
		return false;
 

	
 
	purple_notify_user_info_entry_get_value_wrapped = (purple_notify_user_info_entry_get_value_wrapped_fnc)GetProcAddress(f_hPurple, "purple_notify_user_info_entry_get_value");
 
	if (!purple_notify_user_info_entry_get_value_wrapped)
 
		return false;
 

	
 
	purple_notify_set_ui_ops_wrapped = (purple_notify_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_notify_set_ui_ops");
 
	if (!purple_notify_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_buddy_icons_set_account_icon_wrapped = (purple_buddy_icons_set_account_icon_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_icons_set_account_icon");
 
	if (!purple_buddy_icons_set_account_icon_wrapped)
 
		return false;
 

	
 
	purple_buddy_icons_find_wrapped = (purple_buddy_icons_find_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_icons_find");
 
	if (!purple_buddy_icons_find_wrapped)
 
		return false;
 

	
 
	purple_buddy_icon_get_full_path_wrapped = (purple_buddy_icon_get_full_path_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_icon_get_full_path");
 
	if (!purple_buddy_icon_get_full_path_wrapped)
 
		return false;
 

	
 
	purple_buddy_icon_unref_wrapped = (purple_buddy_icon_unref_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_icon_unref");
 
	if (!purple_buddy_icon_unref_wrapped)
 
		return false;
 

	
 
	purple_buddy_icons_find_account_icon_wrapped = (purple_buddy_icons_find_account_icon_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_icons_find_account_icon");
 
	if (!purple_buddy_icons_find_account_icon_wrapped)
 
		return false;
 

	
 
	purple_buddy_icon_get_data_wrapped = (purple_buddy_icon_get_data_wrapped_fnc)GetProcAddress(f_hPurple, "purple_buddy_icon_get_data");
 
	if (!purple_buddy_icon_get_data_wrapped)
 
		return false;
 

	
 
	purple_account_set_bool_wrapped = (purple_account_set_bool_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_bool");
 
	if (!purple_account_set_bool_wrapped)
 
		return false;
 

	
 
	purple_account_get_protocol_id_wrapped = (purple_account_get_protocol_id_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_get_protocol_id");
 
	if (!purple_account_get_protocol_id_wrapped)
 
		return false;
 

	
 
	purple_account_set_int_wrapped = (purple_account_set_int_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_int");
 
	if (!purple_account_set_int_wrapped)
 
		return false;
 

	
 
	purple_account_set_string_wrapped = (purple_account_set_string_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_string");
 
	if (!purple_account_set_string_wrapped)
 
		return false;
 

	
 
	purple_account_get_username_wrapped = (purple_account_get_username_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_get_username");
 
	if (!purple_account_get_username_wrapped)
 
		return false;
 

	
 
	purple_account_set_username_wrapped = (purple_account_set_username_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_username");
 
	if (!purple_account_set_username_wrapped)
 
		return false;
 

	
 
	purple_accounts_find_wrapped = (purple_accounts_find_wrapped_fnc)GetProcAddress(f_hPurple, "purple_accounts_find");
 
	if (!purple_accounts_find_wrapped)
 
		return false;
 

	
 
	purple_account_new_wrapped = (purple_account_new_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_new");
 
	if (!purple_account_new_wrapped)
 
		return false;
 

	
 
	purple_accounts_add_wrapped = (purple_accounts_add_wrapped_fnc)GetProcAddress(f_hPurple, "purple_accounts_add");
 
	if (!purple_accounts_add_wrapped)
 
		return false;
 

	
 
	purple_account_set_password_wrapped = (purple_account_set_password_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_password");
 
	if (!purple_account_set_password_wrapped)
 
		return false;
 

	
 
	purple_account_set_enabled_wrapped = (purple_account_set_enabled_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_enabled");
 
	if (!purple_account_set_enabled_wrapped)
 
		return false;
 

	
 
	purple_account_set_privacy_type_wrapped = (purple_account_set_privacy_type_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_privacy_type");
 
	if (!purple_account_set_privacy_type_wrapped)
 
		return false;
 

	
 
	purple_account_get_status_type_with_primitive_wrapped = (purple_account_get_status_type_with_primitive_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_get_status_type_with_primitive");
 
	if (!purple_account_get_status_type_with_primitive_wrapped)
 
		return false;
 

	
 
	purple_account_set_status_wrapped = (purple_account_set_status_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_status");
 
	if (!purple_account_set_status_wrapped)
 
		return false;
 

	
 
	purple_account_get_int_wrapped = (purple_account_get_int_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_get_int");
 
	if (!purple_account_get_int_wrapped)
 
		return false;
 

	
 
	purple_account_disconnect_wrapped = (purple_account_disconnect_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_disconnect");
 
	if (!purple_account_disconnect_wrapped)
 
		return false;
 

	
 
	purple_accounts_delete_wrapped = (purple_accounts_delete_wrapped_fnc)GetProcAddress(f_hPurple, "purple_accounts_delete");
 
	if (!purple_accounts_delete_wrapped)
 
		return false;
 

	
 
	purple_account_get_connection_wrapped = (purple_account_get_connection_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_get_connection");
 
	if (!purple_account_get_connection_wrapped)
 
		return false;
 

	
 
	purple_account_set_alias_wrapped = (purple_account_set_alias_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_alias");
 
	if (!purple_account_set_alias_wrapped)
 
		return false;
 

	
 
	purple_account_set_public_alias_wrapped = (purple_account_set_public_alias_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_set_public_alias");
 
	if (!purple_account_set_public_alias_wrapped)
 
		return false;
 

	
 
	purple_account_remove_buddy_wrapped = (purple_account_remove_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_remove_buddy");
 
	if (!purple_account_remove_buddy_wrapped)
 
		return false;
 

	
 
	purple_account_add_buddy_wrapped = (purple_account_add_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_add_buddy");
 
	if (!purple_account_add_buddy_wrapped)
 
		return false;
 

	
 
	purple_account_get_name_for_display_wrapped = (purple_account_get_name_for_display_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_get_name_for_display");
 
	if (!purple_account_get_name_for_display_wrapped)
 
		return false;
 

	
 
	purple_accounts_set_ui_ops_wrapped = (purple_accounts_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_accounts_set_ui_ops");
 
	if (!purple_accounts_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_status_type_get_id_wrapped = (purple_status_type_get_id_wrapped_fnc)GetProcAddress(f_hPurple, "purple_status_type_get_id");
 
	if (!purple_status_type_get_id_wrapped)
 
		return false;
 

	
 
	purple_presence_get_active_status_wrapped = (purple_presence_get_active_status_wrapped_fnc)GetProcAddress(f_hPurple, "purple_presence_get_active_status");
 
	if (!purple_presence_get_active_status_wrapped)
 
		return false;
 

	
 
	purple_status_type_get_primitive_wrapped = (purple_status_type_get_primitive_wrapped_fnc)GetProcAddress(f_hPurple, "purple_status_type_get_primitive");
 
	if (!purple_status_type_get_primitive_wrapped)
 
		return false;
 

	
 
	purple_status_get_type_wrapped = (purple_status_get_type_wrapped_fnc)GetProcAddress(f_hPurple, "purple_status_get_type");
 
	if (!purple_status_get_type_wrapped)
 
		return false;
 

	
 
	purple_status_get_attr_string_wrapped = (purple_status_get_attr_string_wrapped_fnc)GetProcAddress(f_hPurple, "purple_status_get_attr_string");
 
	if (!purple_status_get_attr_string_wrapped)
 
		return false;
 

	
 
	serv_get_info_wrapped = (serv_get_info_wrapped_fnc)GetProcAddress(f_hPurple, "serv_get_info");
 
	if (!serv_get_info_wrapped)
 
		return false;
 

	
 
	serv_alias_buddy_wrapped = (serv_alias_buddy_wrapped_fnc)GetProcAddress(f_hPurple, "serv_alias_buddy");
 
	if (!serv_alias_buddy_wrapped)
 
		return false;
 

	
 
	serv_send_typing_wrapped = (serv_send_typing_wrapped_fnc)GetProcAddress(f_hPurple, "serv_send_typing");
 
	if (!serv_send_typing_wrapped)
 
		return false;
 

	
 
	serv_join_chat_wrapped = (serv_join_chat_wrapped_fnc)GetProcAddress(f_hPurple, "serv_join_chat");
 
	if (!serv_join_chat_wrapped)
 
		return false;
 

	
 
	purple_dnsquery_set_ui_ops_wrapped = (purple_dnsquery_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_dnsquery_set_ui_ops");
 
	if (!purple_dnsquery_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_conversation_get_im_data_wrapped = (purple_conversation_get_im_data_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_get_im_data");
 
	if (!purple_conversation_get_im_data_wrapped)
 
		return false;
 

	
 
	purple_conversation_get_chat_data_wrapped = (purple_conversation_get_chat_data_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_get_chat_data");
 
	if (!purple_conversation_get_chat_data_wrapped)
 
		return false;
 

	
 
	purple_find_conversation_with_account_wrapped = (purple_find_conversation_with_account_wrapped_fnc)GetProcAddress(f_hPurple, "purple_find_conversation_with_account");
 
	if (!purple_find_conversation_with_account_wrapped)
 
		return false;
 

	
 
	purple_conversation_new_wrapped = (purple_conversation_new_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_new");
 
	if (!purple_conversation_new_wrapped)
 
		return false;
 

	
 
	purple_conversation_get_type_wrapped = (purple_conversation_get_type_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_get_type");
 
	if (!purple_conversation_get_type_wrapped)
 
		return false;
 

	
 
	purple_conv_im_send_wrapped = (purple_conv_im_send_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conv_im_send");
 
	if (!purple_conv_im_send_wrapped)
 
		return false;
 

	
 
	purple_conv_chat_send_wrapped = (purple_conv_chat_send_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conv_chat_send");
 
	if (!purple_conv_chat_send_wrapped)
 
		return false;
 

	
 
	purple_conversation_destroy_wrapped = (purple_conversation_destroy_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_destroy");
 
	if (!purple_conversation_destroy_wrapped)
 
		return false;
 

	
 
	purple_conversation_get_account_wrapped = (purple_conversation_get_account_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_get_account");
 
	if (!purple_conversation_get_account_wrapped)
 
		return false;
 

	
 
	purple_conversation_get_name_wrapped = (purple_conversation_get_name_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversation_get_name");
 
	if (!purple_conversation_get_name_wrapped)
 
		return false;
 

	
 
	purple_conversations_set_ui_ops_wrapped = (purple_conversations_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversations_set_ui_ops");
 
	if (!purple_conversations_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_conversations_get_handle_wrapped = (purple_conversations_get_handle_wrapped_fnc)GetProcAddress(f_hPurple, "purple_conversations_get_handle");
 
	if (!purple_conversations_get_handle_wrapped)
 
		return false;
 

	
 
	purple_plugin_action_free_wrapped = (purple_plugin_action_free_wrapped_fnc)GetProcAddress(f_hPurple, "purple_plugin_action_free");
 
	if (!purple_plugin_action_free_wrapped)
 
		return false;
 

	
 
	purple_plugins_add_search_path_wrapped = (purple_plugins_add_search_path_wrapped_fnc)GetProcAddress(f_hPurple, "purple_plugins_add_search_path");
 
	if (!purple_plugins_add_search_path_wrapped)
 
		return false;
 

	
 
	purple_connection_get_state_wrapped = (purple_connection_get_state_wrapped_fnc)GetProcAddress(f_hPurple, "purple_connection_get_state");
 
	if (!purple_connection_get_state_wrapped)
 
		return false;
 

	
 
	purple_connection_get_account_wrapped = (purple_connection_get_account_wrapped_fnc)GetProcAddress(f_hPurple, "purple_connection_get_account");
 
	if (!purple_connection_get_account_wrapped)
 
		return false;
 

	
 
	purple_connection_get_display_name_wrapped = (purple_connection_get_display_name_wrapped_fnc)GetProcAddress(f_hPurple, "purple_connection_get_display_name");
 
	if (!purple_connection_get_display_name_wrapped)
 
		return false;
 

	
 
	purple_connections_set_ui_ops_wrapped = (purple_connections_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_connections_set_ui_ops");
 
	if (!purple_connections_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_connections_get_handle_wrapped = (purple_connections_get_handle_wrapped_fnc)GetProcAddress(f_hPurple, "purple_connections_get_handle");
 
	if (!purple_connections_get_handle_wrapped)
 
		return false;
 

	
 
	purple_core_set_ui_ops_wrapped = (purple_core_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_core_set_ui_ops");
 
	if (!purple_core_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_core_init_wrapped = (purple_core_init_wrapped_fnc)GetProcAddress(f_hPurple, "purple_core_init");
 
	if (!purple_core_init_wrapped)
 
		return false;
 

	
 
	purple_input_add_wrapped = (purple_input_add_wrapped_fnc)GetProcAddress(f_hPurple, "purple_input_add");
 
	if (!purple_input_add_wrapped)
 
		return false;
 

	
 
	purple_timeout_add_wrapped = (purple_timeout_add_wrapped_fnc)GetProcAddress(f_hPurple, "purple_timeout_add");
 
	if (!purple_timeout_add_wrapped)
 
		return false;
 

	
 
	purple_timeout_add_seconds_wrapped = (purple_timeout_add_seconds_wrapped_fnc)GetProcAddress(f_hPurple, "purple_timeout_add_seconds");
 
	if (!purple_timeout_add_seconds_wrapped)
 
		return false;
 

	
 
	purple_timeout_remove_wrapped = (purple_timeout_remove_wrapped_fnc)GetProcAddress(f_hPurple, "purple_timeout_remove");
 
	if (!purple_timeout_remove_wrapped)
 
		return false;
 

	
 
	purple_eventloop_set_ui_ops_wrapped = (purple_eventloop_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_eventloop_set_ui_ops");
 
	if (!purple_eventloop_set_ui_ops_wrapped)
 
		return false;
 

	
 
	purple_input_remove_wrapped = (purple_input_remove_wrapped_fnc)GetProcAddress(f_hPurple, "purple_input_remove");
 
	if (!purple_input_remove_wrapped)
 
		return false;
 

	
 
	purple_privacy_deny_wrapped = (purple_privacy_deny_wrapped_fnc)GetProcAddress(f_hPurple, "purple_privacy_deny");
 
	if (!purple_privacy_deny_wrapped)
 
		return false;
 

	
 
	purple_privacy_allow_wrapped = (purple_privacy_allow_wrapped_fnc)GetProcAddress(f_hPurple, "purple_privacy_allow");
 
	if (!purple_privacy_allow_wrapped)
 
		return false;
 

	
 
	purple_privacy_check_wrapped = (purple_privacy_check_wrapped_fnc)GetProcAddress(f_hPurple, "purple_privacy_check");
 
	if (!purple_privacy_check_wrapped)
 
		return false;
 

	
 
	purple_find_prpl_wrapped = (purple_find_prpl_wrapped_fnc)GetProcAddress(f_hPurple, "purple_find_prpl");
 
	if (!purple_find_prpl_wrapped)
 
		return false;
 

	
 
	purple_prpl_send_attention_wrapped = (purple_prpl_send_attention_wrapped_fnc)GetProcAddress(f_hPurple, "purple_prpl_send_attention");
 
	if (!purple_prpl_send_attention_wrapped)
 
		return false;
 

	
 
	purple_account_option_get_type_wrapped = (purple_account_option_get_type_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_option_get_type");
 
	if (!purple_account_option_get_type_wrapped)
 
		return false;
 

	
 
	purple_account_option_get_setting_wrapped = (purple_account_option_get_setting_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_option_get_setting");
 
	if (!purple_account_option_get_setting_wrapped)
 
		return false;
 

	
 
	wpurple_g_io_channel_win32_new_socket_wrapped = (wpurple_g_io_channel_win32_new_socket_wrapped_fnc)GetProcAddress(f_hPurple, "wpurple_g_io_channel_win32_new_socket");
 
	if (!wpurple_g_io_channel_win32_new_socket_wrapped)
 
		return false;
 

	
 
#endif
 
	return true;
 
}
 

	
backends/libpurple/purple_defs.h
Show inline comments
 
#pragma once
 
#include <string>
 

	
 
#if PURPLE_RUNTIME
 

	
 
#include <Windows.h>
 
#include <purple.h>
 

	
 
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED(n)    (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CHAT_NODE)
 
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(n)   (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_BUDDY_NODE)
 
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CONTACT_NODE)
 
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED(n)   (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_GROUP_NODE)
 

	
 
#define PURPLE_CONV_IM_WRAPPED(c) (purple_conversation_get_im_data_wrapped(c))
 
#define PURPLE_CONV_CHAT_WRAPPED(c) (purple_conversation_get_chat_data_wrapped(c))
 

	
 
#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED(gc) 	(purple_connection_get_state_wrapped(gc) == PURPLE_CONNECTED)
 

	
 
typedef void  (_cdecl * purple_debug_set_ui_ops_wrapped_fnc)(PurpleDebugUiOps *ops);
 
extern purple_debug_set_ui_ops_wrapped_fnc purple_debug_set_ui_ops_wrapped;
 

	
 
typedef void  (_cdecl * purple_debug_set_verbose_wrapped_fnc)(gboolean verbose);
 
extern purple_debug_set_verbose_wrapped_fnc purple_debug_set_verbose_wrapped;
 

	
 
typedef void  (_cdecl * purple_request_set_ui_ops_wrapped_fnc)(PurpleRequestUiOps *ops);
 
extern purple_request_set_ui_ops_wrapped_fnc purple_request_set_ui_ops_wrapped;
 

	
 
typedef gconstpointer  (_cdecl * purple_imgstore_get_data_wrapped_fnc)(PurpleStoredImage *img);
 
extern purple_imgstore_get_data_wrapped_fnc purple_imgstore_get_data_wrapped;
 

	
 
typedef size_t  (_cdecl * purple_imgstore_get_size_wrapped_fnc)(PurpleStoredImage *img);
 
extern purple_imgstore_get_size_wrapped_fnc purple_imgstore_get_size_wrapped;
 

	
 
typedef PurpleStoredImage * (_cdecl * purple_imgstore_unref_wrapped_fnc)(PurpleStoredImage *img);
 
extern purple_imgstore_unref_wrapped_fnc purple_imgstore_unref_wrapped;
 

	
 
typedef gchar * (_cdecl * purple_markup_escape_text_wrapped_fnc)(const gchar *text, gssize length);
 
extern purple_markup_escape_text_wrapped_fnc purple_markup_escape_text_wrapped;
 

	
 
typedef char * (_cdecl * purple_markup_strip_html_wrapped_fnc)(const char *str);
 
extern purple_markup_strip_html_wrapped_fnc purple_markup_strip_html_wrapped;
 

	
 
typedef const char * (_cdecl * purple_normalize_wrapped_fnc)(const PurpleAccount *account, const char *str);
 
extern purple_normalize_wrapped_fnc purple_normalize_wrapped;
 

	
 
typedef gchar * (_cdecl * purple_strdup_withhtml_wrapped_fnc)(const gchar *src);
 
extern purple_strdup_withhtml_wrapped_fnc purple_strdup_withhtml_wrapped;
 

	
 
typedef void  (_cdecl * purple_markup_html_to_xhtml_wrapped_fnc)(const char *html, char **dest_xhtml, char **dest_plain);
 
extern purple_markup_html_to_xhtml_wrapped_fnc purple_markup_html_to_xhtml_wrapped;
 

	
 
typedef gchar * (_cdecl * purple_utf8_try_convert_wrapped_fnc)(const char *str);
 
extern purple_utf8_try_convert_wrapped_fnc purple_utf8_try_convert_wrapped;
 

	
 
typedef void  (_cdecl * purple_util_set_user_dir_wrapped_fnc)(const char *dir);
 
extern purple_util_set_user_dir_wrapped_fnc purple_util_set_user_dir_wrapped;
 

	
 
typedef PurpleBlistNodeType  (_cdecl * purple_blist_node_get_type_wrapped_fnc)(PurpleBlistNode *node);
 
extern purple_blist_node_get_type_wrapped_fnc purple_blist_node_get_type_wrapped;
 

	
 
typedef const char * (_cdecl * purple_buddy_get_alias_wrapped_fnc)(PurpleBuddy *buddy);
 
extern purple_buddy_get_alias_wrapped_fnc purple_buddy_get_alias_wrapped;
 

	
 
typedef const char * (_cdecl * purple_buddy_get_server_alias_wrapped_fnc)(PurpleBuddy *buddy);
 
extern purple_buddy_get_server_alias_wrapped_fnc purple_buddy_get_server_alias_wrapped;
 

	
 
typedef PurpleBuddy * (_cdecl * purple_find_buddy_wrapped_fnc)(PurpleAccount *account, const char *name);
 
extern purple_find_buddy_wrapped_fnc purple_find_buddy_wrapped;
 

	
 
typedef PurpleGroup * (_cdecl * purple_buddy_get_group_wrapped_fnc)(PurpleBuddy *buddy);
 
extern purple_buddy_get_group_wrapped_fnc purple_buddy_get_group_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_remove_buddy_wrapped_fnc)(PurpleBuddy *buddy);
 
extern purple_blist_remove_buddy_wrapped_fnc purple_blist_remove_buddy_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_alias_buddy_wrapped_fnc)(PurpleBuddy *buddy, const char *alias);
 
extern purple_blist_alias_buddy_wrapped_fnc purple_blist_alias_buddy_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_server_alias_buddy_wrapped_fnc)(PurpleBuddy *buddy, const char *alias);
 
extern purple_blist_server_alias_buddy_wrapped_fnc purple_blist_server_alias_buddy_wrapped;
 

	
 
typedef PurpleGroup * (_cdecl * purple_find_group_wrapped_fnc)(const char *name);
 
extern purple_find_group_wrapped_fnc purple_find_group_wrapped;
 

	
 
typedef PurpleGroup * (_cdecl * purple_group_new_wrapped_fnc)(const char *name);
 
extern purple_group_new_wrapped_fnc purple_group_new_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_add_contact_wrapped_fnc)(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
 
extern purple_blist_add_contact_wrapped_fnc purple_blist_add_contact_wrapped;
 

	
 
typedef PurpleContact * (_cdecl * purple_buddy_get_contact_wrapped_fnc)(PurpleBuddy *buddy);
 
extern purple_buddy_get_contact_wrapped_fnc purple_buddy_get_contact_wrapped;
 

	
 
typedef PurpleBuddy * (_cdecl * purple_buddy_new_wrapped_fnc)(PurpleAccount *account, const char *name, const char *alias);
 
extern purple_buddy_new_wrapped_fnc purple_buddy_new_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_add_buddy_wrapped_fnc)(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node);
 
extern purple_blist_add_buddy_wrapped_fnc purple_blist_add_buddy_wrapped;
 

	
 
typedef PurpleChat * (_cdecl * purple_blist_find_chat_wrapped_fnc)(PurpleAccount *account, const char *name);
 
extern purple_blist_find_chat_wrapped_fnc purple_blist_find_chat_wrapped;
 

	
 
typedef GHashTable * (_cdecl * purple_chat_get_components_wrapped_fnc)(PurpleChat *chat);
 
extern purple_chat_get_components_wrapped_fnc purple_chat_get_components_wrapped;
 

	
 
typedef PurplePresence * (_cdecl * purple_buddy_get_presence_wrapped_fnc)(const PurpleBuddy *buddy);
 
extern purple_buddy_get_presence_wrapped_fnc purple_buddy_get_presence_wrapped;
 

	
 
typedef PurpleAccount * (_cdecl * purple_buddy_get_account_wrapped_fnc)(const PurpleBuddy *buddy);
 
extern purple_buddy_get_account_wrapped_fnc purple_buddy_get_account_wrapped;
 

	
 
typedef const char * (_cdecl * purple_buddy_get_name_wrapped_fnc)(const PurpleBuddy *buddy);
 
extern purple_buddy_get_name_wrapped_fnc purple_buddy_get_name_wrapped;
 

	
 
typedef GSList * (_cdecl * purple_find_buddies_wrapped_fnc)(PurpleAccount *account, const char *name);
 
extern purple_find_buddies_wrapped_fnc purple_find_buddies_wrapped;
 

	
 
typedef const char * (_cdecl * purple_group_get_name_wrapped_fnc)(PurpleGroup *group);
 
extern purple_group_get_name_wrapped_fnc purple_group_get_name_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_set_ui_ops_wrapped_fnc)(PurpleBlistUiOps *ops);
 
extern purple_blist_set_ui_ops_wrapped_fnc purple_blist_set_ui_ops_wrapped;
 

	
 
typedef void  (_cdecl * purple_set_blist_wrapped_fnc)(PurpleBuddyList *blist);
 
extern purple_set_blist_wrapped_fnc purple_set_blist_wrapped;
 

	
 
typedef PurpleBuddyList * (_cdecl * purple_blist_new_wrapped_fnc)(void);
 
extern purple_blist_new_wrapped_fnc purple_blist_new_wrapped;
 

	
 
typedef void  (_cdecl * purple_blist_load_wrapped_fnc)(void);
 
extern purple_blist_load_wrapped_fnc purple_blist_load_wrapped;
 

	
 
typedef void * (_cdecl * purple_blist_get_handle_wrapped_fnc)(void);
 
extern purple_blist_get_handle_wrapped_fnc purple_blist_get_handle_wrapped;
 

	
 
typedef void  (_cdecl * purple_xfer_ui_ready_wrapped_fnc)(PurpleXfer *xfer);
 
extern purple_xfer_ui_ready_wrapped_fnc purple_xfer_ui_ready_wrapped;
 

	
 
typedef void  (_cdecl * purple_xfer_request_accepted_wrapped_fnc)(PurpleXfer *xfer, const char *filename);
 
extern purple_xfer_request_accepted_wrapped_fnc purple_xfer_request_accepted_wrapped;
 

	
 
typedef void  (_cdecl * purple_xfer_request_denied_wrapped_fnc)(PurpleXfer *xfer);
 
extern purple_xfer_request_denied_wrapped_fnc purple_xfer_request_denied_wrapped;
 

	
 
typedef PurpleAccount * (_cdecl * purple_xfer_get_account_wrapped_fnc)(const PurpleXfer *xfer);
 
extern purple_xfer_get_account_wrapped_fnc purple_xfer_get_account_wrapped;
 

	
 
typedef const char * (_cdecl * purple_xfer_get_filename_wrapped_fnc)(const PurpleXfer *xfer);
 
extern purple_xfer_get_filename_wrapped_fnc purple_xfer_get_filename_wrapped;
 

	
 
typedef size_t  (_cdecl * purple_xfer_get_size_wrapped_fnc)(const PurpleXfer *xfer);
 
extern purple_xfer_get_size_wrapped_fnc purple_xfer_get_size_wrapped;
 

	
 
typedef void  (_cdecl * purple_xfer_unref_wrapped_fnc)(PurpleXfer *xfer);
 
extern purple_xfer_unref_wrapped_fnc purple_xfer_unref_wrapped;
 

	
 
typedef void  (_cdecl * purple_xfer_ref_wrapped_fnc)(PurpleXfer *xfer);
 
extern purple_xfer_ref_wrapped_fnc purple_xfer_ref_wrapped;
 

	
 
typedef void  (_cdecl * purple_xfers_set_ui_ops_wrapped_fnc)(PurpleXferUiOps *ops);
 
extern purple_xfers_set_ui_ops_wrapped_fnc purple_xfers_set_ui_ops_wrapped;
 

	
 
typedef void * (_cdecl * purple_xfers_get_handle_wrapped_fnc)(void);
 
extern purple_xfers_get_handle_wrapped_fnc purple_xfers_get_handle_wrapped;
 

	
 
typedef gulong  (_cdecl * purple_signal_connect_wrapped_fnc)(void *instance, const char *signal, void *handle, PurpleCallback func, void *data);
 
extern purple_signal_connect_wrapped_fnc purple_signal_connect_wrapped;
 

	
 
typedef gboolean  (_cdecl * purple_prefs_load_wrapped_fnc)(void);
 
extern purple_prefs_load_wrapped_fnc purple_prefs_load_wrapped;
 

	
 
typedef void  (_cdecl * purple_prefs_set_bool_wrapped_fnc)(const char *name, gboolean value);
 
extern purple_prefs_set_bool_wrapped_fnc purple_prefs_set_bool_wrapped;
 

	
 
typedef void  (_cdecl * purple_prefs_set_string_wrapped_fnc)(const char *name, const char *value);
 
extern purple_prefs_set_string_wrapped_fnc purple_prefs_set_string_wrapped;
 

	
 
typedef PurpleNotifyUserInfo * (_cdecl * purple_notify_user_info_new_wrapped_fnc)(void);
 
extern purple_notify_user_info_new_wrapped_fnc purple_notify_user_info_new_wrapped;
 

	
 
typedef void  (_cdecl * purple_notify_user_info_destroy_wrapped_fnc)(PurpleNotifyUserInfo *user_info);
 
extern purple_notify_user_info_destroy_wrapped_fnc purple_notify_user_info_destroy_wrapped;
 

	
 
typedef GList * (_cdecl * purple_notify_user_info_get_entries_wrapped_fnc)(PurpleNotifyUserInfo *user_info);
 
extern purple_notify_user_info_get_entries_wrapped_fnc purple_notify_user_info_get_entries_wrapped;
 

	
 
typedef const gchar * (_cdecl * purple_notify_user_info_entry_get_label_wrapped_fnc)(PurpleNotifyUserInfoEntry *user_info_entry);
 
extern purple_notify_user_info_entry_get_label_wrapped_fnc purple_notify_user_info_entry_get_label_wrapped;
 

	
 
typedef const gchar * (_cdecl * purple_notify_user_info_entry_get_value_wrapped_fnc)(PurpleNotifyUserInfoEntry *user_info_entry);
 
extern purple_notify_user_info_entry_get_value_wrapped_fnc purple_notify_user_info_entry_get_value_wrapped;
 

	
 
typedef void  (_cdecl * purple_notify_set_ui_ops_wrapped_fnc)(PurpleNotifyUiOps *ops);
 
extern purple_notify_set_ui_ops_wrapped_fnc purple_notify_set_ui_ops_wrapped;
 

	
 
typedef PurpleStoredImage * (_cdecl * purple_buddy_icons_set_account_icon_wrapped_fnc)(PurpleAccount *account, guchar *icon_data, size_t icon_len);
 
extern purple_buddy_icons_set_account_icon_wrapped_fnc purple_buddy_icons_set_account_icon_wrapped;
 

	
 
typedef PurpleBuddyIcon * (_cdecl * purple_buddy_icons_find_wrapped_fnc)(PurpleAccount *account, const char *username);
 
extern purple_buddy_icons_find_wrapped_fnc purple_buddy_icons_find_wrapped;
 

	
 
typedef char * (_cdecl * purple_buddy_icon_get_full_path_wrapped_fnc)(PurpleBuddyIcon *icon);
 
extern purple_buddy_icon_get_full_path_wrapped_fnc purple_buddy_icon_get_full_path_wrapped;
 

	
 
typedef PurpleBuddyIcon * (_cdecl * purple_buddy_icon_unref_wrapped_fnc)(PurpleBuddyIcon *icon);
 
extern purple_buddy_icon_unref_wrapped_fnc purple_buddy_icon_unref_wrapped;
 

	
 
typedef PurpleStoredImage * (_cdecl * purple_buddy_icons_find_account_icon_wrapped_fnc)(PurpleAccount *account);
 
extern purple_buddy_icons_find_account_icon_wrapped_fnc purple_buddy_icons_find_account_icon_wrapped;
 

	
 
typedef gconstpointer  (_cdecl * purple_buddy_icon_get_data_wrapped_fnc)(const PurpleBuddyIcon *icon, size_t *len);
 
extern purple_buddy_icon_get_data_wrapped_fnc purple_buddy_icon_get_data_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_bool_wrapped_fnc)(PurpleAccount *account, const char *name, gboolean value);
 
extern purple_account_set_bool_wrapped_fnc purple_account_set_bool_wrapped;
 

	
 
typedef const char * (_cdecl * purple_account_get_protocol_id_wrapped_fnc)(const PurpleAccount *account);
 
extern purple_account_get_protocol_id_wrapped_fnc purple_account_get_protocol_id_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_int_wrapped_fnc)(PurpleAccount *account, const char *name, int value);
 
extern purple_account_set_int_wrapped_fnc purple_account_set_int_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_string_wrapped_fnc)(PurpleAccount *account, const char *name, const char *value);
 
extern purple_account_set_string_wrapped_fnc purple_account_set_string_wrapped;
 

	
 
typedef const char * (_cdecl * purple_account_get_username_wrapped_fnc)(const PurpleAccount *account);
 
extern purple_account_get_username_wrapped_fnc purple_account_get_username_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_username_wrapped_fnc)(PurpleAccount *account, const char *username);
 
extern purple_account_set_username_wrapped_fnc purple_account_set_username_wrapped;
 

	
 
typedef PurpleAccount * (_cdecl * purple_accounts_find_wrapped_fnc)(const char *name, const char *protocol);
 
extern purple_accounts_find_wrapped_fnc purple_accounts_find_wrapped;
 

	
 
typedef PurpleAccount * (_cdecl * purple_account_new_wrapped_fnc)(const char *username, const char *protocol_id);
 
extern purple_account_new_wrapped_fnc purple_account_new_wrapped;
 

	
 
typedef void  (_cdecl * purple_accounts_add_wrapped_fnc)(PurpleAccount *account);
 
extern purple_accounts_add_wrapped_fnc purple_accounts_add_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_password_wrapped_fnc)(PurpleAccount *account, const char *password);
 
extern purple_account_set_password_wrapped_fnc purple_account_set_password_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_enabled_wrapped_fnc)(PurpleAccount *account, const char *ui, gboolean value);
 
extern purple_account_set_enabled_wrapped_fnc purple_account_set_enabled_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_privacy_type_wrapped_fnc)(PurpleAccount *account, PurplePrivacyType privacy_type);
 
extern purple_account_set_privacy_type_wrapped_fnc purple_account_set_privacy_type_wrapped;
 

	
 
typedef PurpleStatusType * (_cdecl * purple_account_get_status_type_with_primitive_wrapped_fnc)( const PurpleAccount *account, PurpleStatusPrimitive primitive);
 
extern purple_account_get_status_type_with_primitive_wrapped_fnc purple_account_get_status_type_with_primitive_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_status_wrapped_fnc)(PurpleAccount *account, const char *status_id, gboolean active, ...);
 
extern purple_account_set_status_wrapped_fnc purple_account_set_status_wrapped;
 

	
 
typedef int  (_cdecl * purple_account_get_int_wrapped_fnc)(const PurpleAccount *account, const char *name, int default_value);
 
extern purple_account_get_int_wrapped_fnc purple_account_get_int_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_disconnect_wrapped_fnc)(PurpleAccount *account);
 
extern purple_account_disconnect_wrapped_fnc purple_account_disconnect_wrapped;
 

	
 
typedef void  (_cdecl * purple_accounts_delete_wrapped_fnc)(PurpleAccount *account);
 
extern purple_accounts_delete_wrapped_fnc purple_accounts_delete_wrapped;
 

	
 
typedef PurpleConnection * (_cdecl * purple_account_get_connection_wrapped_fnc)(const PurpleAccount *account);
 
extern purple_account_get_connection_wrapped_fnc purple_account_get_connection_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_alias_wrapped_fnc)(PurpleAccount *account, const char *alias);
 
extern purple_account_set_alias_wrapped_fnc purple_account_set_alias_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_set_public_alias_wrapped_fnc)(PurpleAccount *account, const char *alias, PurpleSetPublicAliasSuccessCallback success_cb, PurpleSetPublicAliasFailureCallback failure_cb);
 
extern purple_account_set_public_alias_wrapped_fnc purple_account_set_public_alias_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_remove_buddy_wrapped_fnc)(PurpleAccount *account, PurpleBuddy *buddy, PurpleGroup *group);
 
extern purple_account_remove_buddy_wrapped_fnc purple_account_remove_buddy_wrapped;
 

	
 
typedef void  (_cdecl * purple_account_add_buddy_wrapped_fnc)(PurpleAccount *account, PurpleBuddy *buddy);
 
extern purple_account_add_buddy_wrapped_fnc purple_account_add_buddy_wrapped;
 

	
 
typedef const gchar * (_cdecl * purple_account_get_name_for_display_wrapped_fnc)(const PurpleAccount *account);
 
extern purple_account_get_name_for_display_wrapped_fnc purple_account_get_name_for_display_wrapped;
 

	
 
typedef void  (_cdecl * purple_accounts_set_ui_ops_wrapped_fnc)(PurpleAccountUiOps *ops);
 
extern purple_accounts_set_ui_ops_wrapped_fnc purple_accounts_set_ui_ops_wrapped;
 

	
 
typedef const char * (_cdecl * purple_status_type_get_id_wrapped_fnc)(const PurpleStatusType *status_type);
 
extern purple_status_type_get_id_wrapped_fnc purple_status_type_get_id_wrapped;
 

	
 
typedef PurpleStatus * (_cdecl * purple_presence_get_active_status_wrapped_fnc)(const PurplePresence *presence);
 
extern purple_presence_get_active_status_wrapped_fnc purple_presence_get_active_status_wrapped;
 

	
 
typedef PurpleStatusPrimitive  (_cdecl * purple_status_type_get_primitive_wrapped_fnc)( const PurpleStatusType *status_type);
 
extern purple_status_type_get_primitive_wrapped_fnc purple_status_type_get_primitive_wrapped;
 

	
 
typedef PurpleStatusType * (_cdecl * purple_status_get_type_wrapped_fnc)(const PurpleStatus *status);
 
extern purple_status_get_type_wrapped_fnc purple_status_get_type_wrapped;
 

	
 
typedef const char * (_cdecl * purple_status_get_attr_string_wrapped_fnc)(const PurpleStatus *status, const char *id);
 
extern purple_status_get_attr_string_wrapped_fnc purple_status_get_attr_string_wrapped;
 

	
 
typedef void  (_cdecl * serv_get_info_wrapped_fnc)(PurpleConnection *, const char *);
 
extern serv_get_info_wrapped_fnc serv_get_info_wrapped;
 

	
 
typedef void  (_cdecl * serv_alias_buddy_wrapped_fnc)(PurpleBuddy *);
 
extern serv_alias_buddy_wrapped_fnc serv_alias_buddy_wrapped;
 

	
 
typedef unsigned int  (_cdecl * serv_send_typing_wrapped_fnc)(PurpleConnection *gc, const char *name, PurpleTypingState state);
 
extern serv_send_typing_wrapped_fnc serv_send_typing_wrapped;
 

	
 
typedef void  (_cdecl * serv_join_chat_wrapped_fnc)(PurpleConnection *, GHashTable *data);
 
extern serv_join_chat_wrapped_fnc serv_join_chat_wrapped;
 

	
 
typedef void  (_cdecl * purple_dnsquery_set_ui_ops_wrapped_fnc)(PurpleDnsQueryUiOps *ops);
 
extern purple_dnsquery_set_ui_ops_wrapped_fnc purple_dnsquery_set_ui_ops_wrapped;
 

	
 
typedef PurpleConvIm * (_cdecl * purple_conversation_get_im_data_wrapped_fnc)(const PurpleConversation *conv);
 
extern purple_conversation_get_im_data_wrapped_fnc purple_conversation_get_im_data_wrapped;
 

	
 
typedef PurpleConvChat * (_cdecl * purple_conversation_get_chat_data_wrapped_fnc)(const PurpleConversation *conv);
 
extern purple_conversation_get_chat_data_wrapped_fnc purple_conversation_get_chat_data_wrapped;
 

	
 
typedef PurpleConversation * (_cdecl * purple_find_conversation_with_account_wrapped_fnc)( PurpleConversationType type, const char *name, const PurpleAccount *account);
 
extern purple_find_conversation_with_account_wrapped_fnc purple_find_conversation_with_account_wrapped;
 

	
 
typedef PurpleConversation * (_cdecl * purple_conversation_new_wrapped_fnc)(PurpleConversationType type, PurpleAccount *account, const char *name);
 
extern purple_conversation_new_wrapped_fnc purple_conversation_new_wrapped;
 

	
 
typedef PurpleConversationType  (_cdecl * purple_conversation_get_type_wrapped_fnc)(const PurpleConversation *conv);
 
extern purple_conversation_get_type_wrapped_fnc purple_conversation_get_type_wrapped;
 

	
 
typedef void  (_cdecl * purple_conv_im_send_wrapped_fnc)(PurpleConvIm *im, const char *message);
 
extern purple_conv_im_send_wrapped_fnc purple_conv_im_send_wrapped;
 

	
 
typedef void  (_cdecl * purple_conv_chat_send_wrapped_fnc)(PurpleConvChat *chat, const char *message);
 
extern purple_conv_chat_send_wrapped_fnc purple_conv_chat_send_wrapped;
 

	
 
typedef void  (_cdecl * purple_conversation_destroy_wrapped_fnc)(PurpleConversation *conv);
 
extern purple_conversation_destroy_wrapped_fnc purple_conversation_destroy_wrapped;
 

	
 
typedef PurpleAccount * (_cdecl * purple_conversation_get_account_wrapped_fnc)(const PurpleConversation *conv);
 
extern purple_conversation_get_account_wrapped_fnc purple_conversation_get_account_wrapped;
 

	
 
typedef const char * (_cdecl * purple_conversation_get_name_wrapped_fnc)(const PurpleConversation *conv);
 
extern purple_conversation_get_name_wrapped_fnc purple_conversation_get_name_wrapped;
 

	
 
typedef void  (_cdecl * purple_conversations_set_ui_ops_wrapped_fnc)(PurpleConversationUiOps *ops);
 
extern purple_conversations_set_ui_ops_wrapped_fnc purple_conversations_set_ui_ops_wrapped;
 

	
 
typedef void * (_cdecl * purple_conversations_get_handle_wrapped_fnc)(void);
 
extern purple_conversations_get_handle_wrapped_fnc purple_conversations_get_handle_wrapped;
 

	
 
typedef void  (_cdecl * purple_plugin_action_free_wrapped_fnc)(PurplePluginAction *action);
 
extern purple_plugin_action_free_wrapped_fnc purple_plugin_action_free_wrapped;
 

	
 
typedef void  (_cdecl * purple_plugins_add_search_path_wrapped_fnc)(const char *path);
 
extern purple_plugins_add_search_path_wrapped_fnc purple_plugins_add_search_path_wrapped;
 

	
 
typedef void  (_cdecl * purple_certificate_add_ca_search_path_wrapped_fnc)(const char *path);
 
extern purple_certificate_add_ca_search_path_wrapped_fnc purple_certificate_add_ca_search_path_wrapped;
 

	
 
typedef PurpleConnectionState  (_cdecl * purple_connection_get_state_wrapped_fnc)(const PurpleConnection *gc);
 
extern purple_connection_get_state_wrapped_fnc purple_connection_get_state_wrapped;
 

	
 
typedef PurpleAccount * (_cdecl * purple_connection_get_account_wrapped_fnc)(const PurpleConnection *gc);
 
extern purple_connection_get_account_wrapped_fnc purple_connection_get_account_wrapped;
 

	
 
typedef const char * (_cdecl * purple_connection_get_display_name_wrapped_fnc)(const PurpleConnection *gc);
 
extern purple_connection_get_display_name_wrapped_fnc purple_connection_get_display_name_wrapped;
 

	
 
typedef void  (_cdecl * purple_connections_set_ui_ops_wrapped_fnc)(PurpleConnectionUiOps *ops);
 
extern purple_connections_set_ui_ops_wrapped_fnc purple_connections_set_ui_ops_wrapped;
 

	
 
typedef void * (_cdecl * purple_connections_get_handle_wrapped_fnc)(void);
 
extern purple_connections_get_handle_wrapped_fnc purple_connections_get_handle_wrapped;
 

	
 
typedef void  (_cdecl * purple_core_set_ui_ops_wrapped_fnc)(PurpleCoreUiOps *ops);
 
extern purple_core_set_ui_ops_wrapped_fnc purple_core_set_ui_ops_wrapped;
 

	
 
typedef gboolean  (_cdecl * purple_core_init_wrapped_fnc)(const char *ui);
 
extern purple_core_init_wrapped_fnc purple_core_init_wrapped;
 

	
 
typedef guint  (_cdecl * purple_input_add_wrapped_fnc)(int fd, PurpleInputCondition cond, PurpleInputFunction func, gpointer user_data);
 
extern purple_input_add_wrapped_fnc purple_input_add_wrapped;
 

	
 
typedef guint  (_cdecl * purple_timeout_add_wrapped_fnc)(guint interval, GSourceFunc function, gpointer data);
 
extern purple_timeout_add_wrapped_fnc purple_timeout_add_wrapped;
 

	
 
typedef guint  (_cdecl * purple_timeout_add_seconds_wrapped_fnc)(guint interval, GSourceFunc function, gpointer data);
 
extern purple_timeout_add_seconds_wrapped_fnc purple_timeout_add_seconds_wrapped;
 

	
 
typedef gboolean  (_cdecl * purple_timeout_remove_wrapped_fnc)(guint handle);
 
extern purple_timeout_remove_wrapped_fnc purple_timeout_remove_wrapped;
 

	
 
typedef void  (_cdecl * purple_eventloop_set_ui_ops_wrapped_fnc)(PurpleEventLoopUiOps *ops);
 
extern purple_eventloop_set_ui_ops_wrapped_fnc purple_eventloop_set_ui_ops_wrapped;
 

	
 
typedef gboolean  (_cdecl * purple_input_remove_wrapped_fnc)(guint handle);
 
extern purple_input_remove_wrapped_fnc purple_input_remove_wrapped;
 

	
 
typedef void  (_cdecl * purple_privacy_deny_wrapped_fnc)(PurpleAccount *account, const char *who, gboolean local, gboolean restore);
 
extern purple_privacy_deny_wrapped_fnc purple_privacy_deny_wrapped;
 

	
 
typedef void  (_cdecl * purple_privacy_allow_wrapped_fnc)(PurpleAccount *account, const char *who, gboolean local, gboolean restore);
 
extern purple_privacy_allow_wrapped_fnc purple_privacy_allow_wrapped;
 

	
 
typedef gboolean  (_cdecl * purple_privacy_check_wrapped_fnc)(PurpleAccount *account, const char *who);
 
extern purple_privacy_check_wrapped_fnc purple_privacy_check_wrapped;
 

	
 
typedef PurplePlugin * (_cdecl * purple_find_prpl_wrapped_fnc)(const char *id);
 
extern purple_find_prpl_wrapped_fnc purple_find_prpl_wrapped;
 

	
 
typedef void  (_cdecl * purple_prpl_send_attention_wrapped_fnc)(PurpleConnection *gc, const char *who, guint type_code);
 
extern purple_prpl_send_attention_wrapped_fnc purple_prpl_send_attention_wrapped;
 

	
 
typedef PurplePrefType  (_cdecl * purple_account_option_get_type_wrapped_fnc)(const PurpleAccountOption *option);
 
extern purple_account_option_get_type_wrapped_fnc purple_account_option_get_type_wrapped;
 

	
 
typedef const char * (_cdecl * purple_account_option_get_setting_wrapped_fnc)(const PurpleAccountOption *option);
 
extern purple_account_option_get_setting_wrapped_fnc purple_account_option_get_setting_wrapped;
 

	
 
typedef GIOChannel * (_cdecl * wpurple_g_io_channel_win32_new_socket_wrapped_fnc)(int socket);
 
extern wpurple_g_io_channel_win32_new_socket_wrapped_fnc wpurple_g_io_channel_win32_new_socket_wrapped;
 

	
 

	
 
#else
 

	
 

	
 
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED PURPLE_BLIST_NODE_IS_CHAT
 
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED PURPLE_BLIST_NODE_IS_BUDDY
 
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED PURPLE_BLIST_NODE_IS_CONTACT
 
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED PURPLE_BLIST_NODE_IS_GROUP
 

	
 
#define PURPLE_CONV_IM_WRAPPED PURPLE_CONV_IM
 
#define PURPLE_CONV_CHAT_WRAPPED PURPLE_CONV_CHAT
 

	
 
#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED PURPLE_CONNECTION_IS_CONNECTED	
 

	
 
#define purple_debug_set_ui_ops_wrapped purple_debug_set_ui_ops
 
#define purple_debug_set_verbose_wrapped purple_debug_set_verbose
 
#define purple_request_set_ui_ops_wrapped purple_request_set_ui_ops
 
#define purple_imgstore_get_data_wrapped purple_imgstore_get_data
 
#define purple_imgstore_get_size_wrapped purple_imgstore_get_size
 
#define purple_imgstore_unref_wrapped purple_imgstore_unref
 
#define purple_markup_escape_text_wrapped purple_markup_escape_text
 
#define purple_markup_strip_html_wrapped purple_markup_strip_html
 
#define purple_normalize_wrapped purple_normalize
 
#define purple_strdup_withhtml_wrapped purple_strdup_withhtml
 
#define purple_markup_html_to_xhtml_wrapped purple_markup_html_to_xhtml
 
#define purple_utf8_try_convert_wrapped purple_utf8_try_convert
 
#define purple_util_set_user_dir_wrapped purple_util_set_user_dir
 
#define purple_blist_node_get_type_wrapped purple_blist_node_get_type
 
#define purple_buddy_get_alias_wrapped purple_buddy_get_alias
 
#define purple_buddy_get_server_alias_wrapped purple_buddy_get_server_alias
 
#define purple_find_buddy_wrapped purple_find_buddy
 
#define purple_buddy_get_group_wrapped purple_buddy_get_group
 
#define purple_blist_remove_buddy_wrapped purple_blist_remove_buddy
 
#define purple_blist_alias_buddy_wrapped purple_blist_alias_buddy
 
#define purple_blist_server_alias_buddy_wrapped purple_blist_server_alias_buddy
 
#define purple_find_group_wrapped purple_find_group
 
#define purple_group_new_wrapped purple_group_new
 
#define purple_blist_add_contact_wrapped purple_blist_add_contact
 
#define purple_buddy_get_contact_wrapped purple_buddy_get_contact
 
#define purple_buddy_new_wrapped purple_buddy_new
 
#define purple_blist_add_buddy_wrapped purple_blist_add_buddy
 
#define purple_blist_find_chat_wrapped purple_blist_find_chat
 
#define purple_chat_get_components_wrapped purple_chat_get_components
 
#define purple_buddy_get_presence_wrapped purple_buddy_get_presence
 
#define purple_buddy_get_account_wrapped purple_buddy_get_account
 
#define purple_buddy_get_name_wrapped purple_buddy_get_name
 
#define purple_find_buddies_wrapped purple_find_buddies
 
#define purple_group_get_name_wrapped purple_group_get_name
 
#define purple_blist_set_ui_ops_wrapped purple_blist_set_ui_ops
 
#define purple_set_blist_wrapped purple_set_blist
 
#define purple_blist_new_wrapped purple_blist_new
 
#define purple_blist_load_wrapped purple_blist_load
 
#define purple_blist_get_handle_wrapped purple_blist_get_handle
 
#define purple_xfer_ui_ready_wrapped purple_xfer_ui_ready
 
#define purple_xfer_request_accepted_wrapped purple_xfer_request_accepted
 
#define purple_xfer_request_denied_wrapped purple_xfer_request_denied
 
#define purple_xfer_get_account_wrapped purple_xfer_get_account
 
#define purple_xfer_get_filename_wrapped purple_xfer_get_filename
 
#define purple_xfer_get_size_wrapped purple_xfer_get_size
 
#define purple_xfer_unref_wrapped purple_xfer_unref
 
#define purple_xfer_ref_wrapped purple_xfer_ref
 
#define purple_xfers_set_ui_ops_wrapped purple_xfers_set_ui_ops
 
#define purple_xfers_get_handle_wrapped purple_xfers_get_handle
 
#define purple_signal_connect_wrapped purple_signal_connect
 
#define purple_prefs_load_wrapped purple_prefs_load
 
#define purple_prefs_set_bool_wrapped purple_prefs_set_bool
 
#define purple_prefs_set_string_wrapped purple_prefs_set_string
 
#define purple_notify_user_info_new_wrapped purple_notify_user_info_new
 
#define purple_notify_user_info_destroy_wrapped purple_notify_user_info_destroy
 
#define purple_notify_user_info_get_entries_wrapped purple_notify_user_info_get_entries
 
#define purple_notify_user_info_entry_get_label_wrapped purple_notify_user_info_entry_get_label
 
#define purple_notify_user_info_entry_get_value_wrapped purple_notify_user_info_entry_get_value
 
#define purple_notify_set_ui_ops_wrapped purple_notify_set_ui_ops
 
#define purple_buddy_icons_set_account_icon_wrapped purple_buddy_icons_set_account_icon
 
#define purple_buddy_icons_find_wrapped purple_buddy_icons_find
 
#define purple_buddy_icon_get_full_path_wrapped purple_buddy_icon_get_full_path
 
#define purple_buddy_icon_unref_wrapped purple_buddy_icon_unref
 
#define purple_buddy_icons_find_account_icon_wrapped purple_buddy_icons_find_account_icon
 
#define purple_buddy_icon_get_data_wrapped purple_buddy_icon_get_data
 
#define purple_account_set_bool_wrapped purple_account_set_bool
 
#define purple_account_get_protocol_id_wrapped purple_account_get_protocol_id
 
#define purple_account_set_int_wrapped purple_account_set_int
 
#define purple_account_set_string_wrapped purple_account_set_string
 
#define purple_account_get_username_wrapped purple_account_get_username
 
#define purple_account_set_username_wrapped purple_account_set_username
 
#define purple_accounts_find_wrapped purple_accounts_find
 
#define purple_account_new_wrapped purple_account_new
 
#define purple_accounts_add_wrapped purple_accounts_add
 
#define purple_account_set_password_wrapped purple_account_set_password
 
#define purple_account_set_enabled_wrapped purple_account_set_enabled
 
#define purple_account_set_privacy_type_wrapped purple_account_set_privacy_type
 
#define purple_account_get_status_type_with_primitive_wrapped purple_account_get_status_type_with_primitive
 
#define purple_account_set_status_wrapped purple_account_set_status
 
#define purple_account_get_int_wrapped purple_account_get_int
 
#define purple_account_disconnect_wrapped purple_account_disconnect
 
#define purple_accounts_delete_wrapped purple_accounts_delete
 
#define purple_account_get_connection_wrapped purple_account_get_connection
 
#define purple_account_set_alias_wrapped purple_account_set_alias
 
#define purple_account_set_public_alias_wrapped purple_account_set_public_alias
 
#define purple_account_remove_buddy_wrapped purple_account_remove_buddy
 
#define purple_account_add_buddy_wrapped purple_account_add_buddy
 
#define purple_account_get_name_for_display_wrapped purple_account_get_name_for_display
 
#define purple_accounts_set_ui_ops_wrapped purple_accounts_set_ui_ops
 
#define purple_status_type_get_id_wrapped purple_status_type_get_id
 
#define purple_presence_get_active_status_wrapped purple_presence_get_active_status
 
#define purple_status_type_get_primitive_wrapped purple_status_type_get_primitive
 
#define purple_status_get_type_wrapped purple_status_get_type
 
#define purple_status_get_attr_string_wrapped purple_status_get_attr_string
 
#define serv_get_info_wrapped serv_get_info
 
#define serv_alias_buddy_wrapped serv_alias_buddy
 
#define serv_send_typing_wrapped serv_send_typing
 
#define serv_join_chat_wrapped serv_join_chat
 
#define purple_dnsquery_set_ui_ops_wrapped purple_dnsquery_set_ui_ops
 
#define purple_conversation_get_im_data_wrapped purple_conversation_get_im_data
 
#define purple_conversation_get_chat_data_wrapped purple_conversation_get_chat_data
 
#define purple_find_conversation_with_account_wrapped purple_find_conversation_with_account
 
#define purple_conversation_new_wrapped purple_conversation_new
 
#define purple_conversation_get_type_wrapped purple_conversation_get_type
 
#define purple_conv_im_send_wrapped purple_conv_im_send
 
#define purple_conv_chat_send_wrapped purple_conv_chat_send
 
#define purple_conversation_destroy_wrapped purple_conversation_destroy
 
#define purple_conversation_get_account_wrapped purple_conversation_get_account
 
#define purple_conversation_get_name_wrapped purple_conversation_get_name
 
#define purple_conversations_set_ui_ops_wrapped purple_conversations_set_ui_ops
 
#define purple_conversations_get_handle_wrapped purple_conversations_get_handle
 
#define purple_plugin_action_free_wrapped purple_plugin_action_free
 
#define purple_certificate_add_ca_search_path_wrapped purple_certificate_add_ca_search_path
 
#define purple_plugins_add_search_path_wrapped purple_plugins_add_search_path
 
#define purple_connection_get_state_wrapped purple_connection_get_state
 
#define purple_connection_get_account_wrapped purple_connection_get_account
 
#define purple_connection_get_display_name_wrapped purple_connection_get_display_name
 
#define purple_connections_set_ui_ops_wrapped purple_connections_set_ui_ops
 
#define purple_connections_get_handle_wrapped purple_connections_get_handle
 
#define purple_core_set_ui_ops_wrapped purple_core_set_ui_ops
 
#define purple_core_init_wrapped purple_core_init
 
#define purple_input_add_wrapped purple_input_add
 
#define purple_timeout_add_wrapped purple_timeout_add
 
#define purple_timeout_add_seconds_wrapped purple_timeout_add_seconds
 
#define purple_timeout_remove_wrapped purple_timeout_remove
 
#define purple_eventloop_set_ui_ops_wrapped purple_eventloop_set_ui_ops
 
#define purple_input_remove_wrapped purple_input_remove
 
#define purple_privacy_deny_wrapped purple_privacy_deny
 
#define purple_privacy_allow_wrapped purple_privacy_allow
 
#define purple_privacy_check_wrapped purple_privacy_check
 
#define purple_find_prpl_wrapped purple_find_prpl
 
#define purple_prpl_send_attention_wrapped purple_prpl_send_attention
 
#define purple_account_option_get_type_wrapped purple_account_option_get_type
 
#define purple_account_option_get_setting_wrapped purple_account_option_get_setting
 
#define wpurple_g_io_channel_win32_new_socket_wrapped wpurple_g_io_channel_win32_new_socket
 
#endif
 

	
 
bool resolvePurpleFunctions(const std::string& libPurpleDllPath);
 

	
 
bool resolvePurpleFunctions();
backends/libpurple/utils.cpp
Show inline comments
 
@@ -18,14 +18,20 @@
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
// win32/libc_interface.h defines its own socket(), read() and so on.
 
// We don't want to use it here.
 
#define _LIBC_INTERFACE_H_ 1
 

	
 
#include "utils.h"
 

	
 
#include "glib.h"
 
#include "purple.h"
 
#include <algorithm>
 
#include <iostream>
 
#include <vector>
 

	
 
#include "errno.h"
 
#include <string.h>
 

	
 
#ifndef WIN32 
 
#include "sys/wait.h"
 
@@ -45,14 +51,19 @@
 
#define getpid _getpid 
 
#define ssize_t SSIZE_T
 
#include "win32/win32dep.h"
 
#define close closesocket
 
#endif
 

	
 
#include "purple_defs.h"
 

	
 
#include <boost/numeric/conversion/cast.hpp>
 

	
 
using std::vector;
 

	
 
static GHashTable *ui_info = NULL;
 

	
 
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name) {
 
	PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
 
	PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED_WRAPPED(gc) ? gc->prpl : NULL;
 
	if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
 
		PurplePluginAction *action = NULL;
 
		GList *actions, *l;
 
@@ -67,7 +78,7 @@ void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name)
 
				if ((std::string) action->label == name) {
 
					action->callback(action);
 
				}
 
				purple_plugin_action_free(action);
 
				purple_plugin_action_free_wrapped(action);
 
			}
 
		}
 
	}
 
@@ -125,7 +136,7 @@ void spectrum_sigchld_handler(int sig)
 
}
 
#endif
 

	
 
int create_socket(char *host, int portno) {
 
int create_socket(const char *host, int portno) {
 
	struct sockaddr_in serv_addr;
 
	
 
	int main_socket = socket(AF_INET, SOCK_STREAM, 0);
 
@@ -151,3 +162,34 @@ int create_socket(char *host, int portno) {
 
// 	fcntl(main_socket, F_SETFL, flags);
 
	return main_socket;
 
}
 

	
 
#ifdef _WIN32
 
std::wstring utf8ToUtf16(const std::string& str)
 
{
 
	try
 
	{
 
		if (str.empty())
 
			return L"";
 

	
 
		// First request the size of the required UTF-16 buffer
 
		int numRequiredBytes = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), boost::numeric_cast<int>(str.size()), NULL, 0);
 
		if (!numRequiredBytes)
 
			return L"";
 

	
 
		// Allocate memory for the UTF-16 string
 
		std::vector<wchar_t> utf16Str(numRequiredBytes);
 

	
 
		int numConverted = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), boost::numeric_cast<int>(str.size()), &utf16Str[0], numRequiredBytes);
 
		if (!numConverted)
 
			return L"";
 

	
 
		std::wstring wstr(&utf16Str[0], numConverted);
 
		return wstr;
 
	}
 
	catch (...)
 
	{
 
		// I don't believe libtransport is exception-safe so we'll just return an empty string instead
 
		return L"";
 
	}
 
}
 
#endif // _WIN32
backends/libpurple/utils.h
Show inline comments
 
@@ -27,7 +27,11 @@
 
void spectrum_sigchld_handler(int sig);
 
#endif
 

	
 
int create_socket(char *host, int portno);
 
int create_socket(const char *host, int portno);
 
GHashTable *spectrum_ui_get_info(void);
 

	
 
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name);
 

	
 
#ifdef _WIN32
 
	std::wstring utf8ToUtf16(const std::string& str);
 
#endif
backends/libyahoo2/CMakeLists.txt
Show inline comments
 
new file 100644
 
cmake_minimum_required(VERSION 2.6)
 
 
FILE(GLOB_RECURSE SRC *.c *.cpp)
 
 
ADD_DEFINITIONS(-DHAVE_STDINT_H=1)
 
 
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/yahoo)
 
 
ADD_EXECUTABLE(spectrum2_libyahoo2_backend ${SRC})
 
 
target_link_libraries(spectrum2_libyahoo2_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
 
 
INSTALL(TARGETS spectrum2_libyahoo2_backend RUNTIME DESTINATION bin)
 
backends/libyahoo2/httpfetch.cpp
Show inline comments
 
new file 100644
 

	
 
#include "httpfetch.h"
 
#include "transport/logging.h"
 

	
 
#if WIN32
 
#define snprintf sprintf_s
 
#endif
 

	
 
DEFINE_LOGGER(logger, "HTTPFetch");
 

	
 
static int url_to_host_port_path(const char *url,
 
	char *host, int *port, char *path, int *ssl)
 
{
 
	char *urlcopy = NULL;
 
	char *slash = NULL;
 
	char *colon = NULL;
 

	
 
	/*
 
	 * http://hostname
 
	 * http://hostname/
 
	 * http://hostname/path
 
	 * http://hostname/path:foo
 
	 * http://hostname:port
 
	 * http://hostname:port/
 
	 * http://hostname:port/path
 
	 * http://hostname:port/path:foo
 
	 * and https:// variants of the above
 
	 */
 

	
 
	if (strstr(url, "http://") == url) {
 
		urlcopy = strdup(url + 7);
 
	} else if (strstr(url, "https://") == url) {
 
		urlcopy = strdup(url + 8);
 
		*ssl = 1;
 
	} else {
 
		return 0;
 
	}
 

	
 
	slash = strchr(urlcopy, '/');
 
	colon = strchr(urlcopy, ':');
 

	
 
	if (!colon || (slash && slash < colon)) {
 
		if (*ssl)
 
			*port = 443;
 
		else
 
			*port = 80;
 
	} else {
 
		*colon = 0;
 
		*port = atoi(colon + 1);
 
	}
 

	
 
	if (!slash) {
 
		strcpy(path, "/");
 
	} else {
 
		strcpy(path, slash);
 
		*slash = 0;
 
	}
 

	
 
	strcpy(host, urlcopy);
 

	
 
	free(urlcopy);
 

	
 
	return 1;
 
}
 

	
 
HTTPFetch::HTTPFetch(Swift::BoostIOServiceThread *ioService, Swift::ConnectionFactory *factory) : m_ioService(ioService), m_factory(factory) {
 
	m_afterHeader = false;
 
}
 

	
 
HTTPFetch::~HTTPFetch() {
 
}
 

	
 
void HTTPFetch::_connected(boost::shared_ptr<Swift::Connection> conn, const std::string url, bool error) {
 
	if (error) {
 
		_disconnected(conn);
 
	}
 
	else {
 
		char host[255];
 
		int port = 80;
 
		char path[255];
 
		int ssl = 0;
 
		if (!url_to_host_port_path(url.c_str(), host, &port, path, &ssl))
 
			return;
 

	
 
		static char buff[2048];
 
		snprintf(buff, sizeof(buff),
 
			"GET %s HTTP/1.1\r\n"
 
			"Host: %s\r\n"
 
			"User-Agent: Mozilla/4.5 [en] (1/1)\r\n"
 
			"Accept: */*\r\n"
 
			"%s" "\r\n", path, host,
 
			"Connection: close\r\n");
 
		LOG4CXX_INFO(logger, "Sending " << buff << "\n");
 
		conn->write(Swift::createSafeByteArray(buff));
 
	}
 
}
 

	
 
void HTTPFetch::_disconnected(boost::shared_ptr<Swift::Connection> conn) {
 
	conn->onConnectFinished.disconnect_all_slots();
 
	conn->onDisconnected.disconnect_all_slots();
 
	conn->onDataRead.disconnect_all_slots();
 

	
 
	if (m_buffer.size() == 0) {
 
		onURLFetched("");
 
	}
 
	else {
 
		std::string img = m_buffer.substr(m_buffer.find("\r\n\r\n") + 4);
 
		onURLFetched(img);
 
	}
 
}
 

	
 
void HTTPFetch::_read(boost::shared_ptr<Swift::Connection> conn, boost::shared_ptr<Swift::SafeByteArray> data) {
 
	std::string d(data->begin(), data->end());
 
// 			std::cout << d << "\n";
 
	std::string img = d.substr(d.find("\r\n\r\n") + 4);
 
	if (d.find("Location: ") == std::string::npos) {
 
		m_buffer += d;
 
	}
 
	else {
 
		d = d.substr(d.find("Location: ") + 10);
 
		if (d.find("\r") == std::string::npos) {
 
			d = d.substr(0, d.find("\n"));
 
		}
 
		else {
 
			d = d.substr(0, d.find("\r"));
 
		}
 
		LOG4CXX_INFO(logger, "Next url is '" << d << "'");
 
		fetchURL(d);
 
		conn->onConnectFinished.disconnect_all_slots();
 
		conn->onDisconnected.disconnect_all_slots();
 
		conn->onDataRead.disconnect_all_slots();
 
	}
 
}
 

	
 
bool HTTPFetch::fetchURL(const std::string &url) {
 
	char host[255];
 
	int port = 80;
 
	char path[255];
 
	char buff[1024];
 
	int ssl = 0;
 
	if (!url_to_host_port_path(url.c_str(), host, &port, path, &ssl)) {
 
		LOG4CXX_ERROR(logger, "Invalid URL " << url);
 
		return false;
 
	}
 

	
 
	LOG4CXX_INFO(logger, "Connecting to " << host << ":" << port);
 

	
 
	boost::asio::ip::tcp::resolver resolver(*m_ioService->getIOService());
 
	boost::asio::ip::tcp::resolver::query query(host, "");
 
	boost::asio::ip::address address;
 
	for(boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); i != boost::asio::ip::tcp::resolver::iterator(); ++i) {
 
		boost::asio::ip::tcp::endpoint end = *i;
 
		address = end.address();
 
		break;
 
	}
 

	
 
	boost::shared_ptr<Swift::Connection> conn = m_factory->createConnection();
 
	conn->onConnectFinished.connect(boost::bind(&HTTPFetch::_connected, this, conn, url, _1));
 
	conn->onDisconnected.connect(boost::bind(&HTTPFetch::_disconnected, this, conn));
 
	conn->onDataRead.connect(boost::bind(&HTTPFetch::_read, this, conn, _1));
 
	conn->connect(Swift::HostAddressPort(Swift::HostAddress(address), port));
 
	return true;
 
}
backends/libyahoo2/httpfetch.h
Show inline comments
 
new file 100644
 
#pragma once
 

	
 
// Transport includes
 
#include "transport/config.h"
 
#include "transport/networkplugin.h"
 
#include "transport/logging.h"
 

	
 
// Swiften
 
#include "Swiften/Swiften.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
 

	
 
// Boost
 
#include <boost/algorithm/string.hpp>
 

	
 
using namespace boost::filesystem;
 
using namespace boost::program_options;
 
using namespace Transport;
 

	
 
class HTTPFetch {
 
	public:
 
		HTTPFetch(Swift::BoostIOServiceThread *ioSerice, Swift::ConnectionFactory *factory);
 
		virtual ~HTTPFetch();
 

	
 
		bool fetchURL(const std::string &url);
 

	
 
		boost::signal<void (const std::string &data)> onURLFetched;
 

	
 
	private:
 
		void _connected(boost::shared_ptr<Swift::Connection> conn, const std::string url, bool error);
 
		void _disconnected(boost::shared_ptr<Swift::Connection> conn);
 
		void _read(boost::shared_ptr<Swift::Connection> conn, boost::shared_ptr<Swift::SafeByteArray> data);
 

	
 
		Swift::BoostIOServiceThread *m_ioService;
 
		Swift::ConnectionFactory *m_factory;
 
		std::string m_buffer;
 
		bool m_afterHeader;
 
};
backends/libyahoo2/main.cpp
Show inline comments
 
new file 100644
 
// Transport includes
 
#include "transport/config.h"
 
#include "transport/networkplugin.h"
 
#include "transport/logging.h"
 

	
 
// Yahoo2
 
#include <yahoo2.h>
 
#include <yahoo2_callbacks.h>
 
#include <stdio.h>
 
#include <stdarg.h>
 
#include <stdlib.h>
 

	
 
#include "yahoohandler.h"
 
#include "yahoolocalaccount.h"
 
#include "httpfetch.h"
 

	
 
// Swiften
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Network/TLSConnectionFactory.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
 

	
 
#ifndef _WIN32
 
// for signal handler
 
#include "unistd.h"
 
#include "signal.h"
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
#endif
 

	
 
// Boost
 
#include <boost/algorithm/string.hpp>
 
using namespace boost::filesystem;
 
using namespace boost::program_options;
 
using namespace Transport;
 

	
 
class YahooHandler;
 
class YahooLocalAccount;
 

	
 
static std::string *currently_read_data;
 
static YahooLocalAccount *currently_writting_account;
 

	
 
YahooHandler::YahooHandler(YahooLocalAccount *account, int conn_tag, int handler_tag, void *data, yahoo_input_condition cond) :
 
	handler_tag(handler_tag), conn_tag(conn_tag), data(data), cond(cond), remove_later(false), account(account) {}
 

	
 
YahooHandler::~YahooHandler() {}
 

	
 
void YahooHandler::ready(std::string *buffer) {
 
	if (cond == YAHOO_INPUT_WRITE) {
 
		YahooLocalAccount *old = currently_writting_account;
 
		currently_writting_account = account;
 
		yahoo_write_ready(account->id, (void *) conn_tag, data);
 
		currently_writting_account = old;
 
	}
 
	else {
 
		if (!buffer) {
 
			return;
 
		}
 
		// yahoo_read_ready calls ext_yahoo_read(...) in a loop, so we just have to choose proper buffer from which will
 
		// that method read. We do that by static currently_read_data pointer.
 
		currently_read_data = buffer;
 
		// libyahoo2 reads data per 1024 bytes, so if we still have some data after the first ext_yahoo_read call,
 
		// we have to call yahoo_read_ready again...
 
		do {
 
			yahoo_read_ready(account->id, (void *) conn_tag, data);
 
		} while (currently_read_data->size() != 0);
 
	}
 
}
 

	
 

	
 
typedef struct {
 
	std::string yahoo_id;
 
	std::string name;
 
	int status;
 
	int away;
 
	std::string msg;
 
	std::string group;
 
} yahoo_account;
 

	
 
typedef struct {
 
	int id;
 
	char *label;
 
} yahoo_idlabel;
 

	
 
typedef struct {
 
	int id;
 
	char *who;
 
} yahoo_authorize_data;
 

	
 
DEFINE_LOGGER(logger, "Yahoo2");
 

	
 
// eventloop
 
Swift::SimpleEventLoop *loop_;
 

	
 
// Plugin
 
class YahooPlugin;
 
YahooPlugin * np = NULL;
 

	
 
class YahooPlugin : public NetworkPlugin {
 
	public:
 
		Swift::BoostNetworkFactories *m_factories;
 
		Swift::OpenSSLContextFactory *m_sslFactory;
 
		Swift::TLSConnectionFactory *m_tlsFactory;
 
		Swift::BoostIOServiceThread m_boostIOServiceThread;
 
		boost::shared_ptr<Swift::Connection> m_conn;
 

	
 
		YahooPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
 
			this->config = config;
 
			m_factories = new Swift::BoostNetworkFactories(loop);
 
			m_sslFactory = new Swift::OpenSSLContextFactory();
 
			m_tlsFactory = new Swift::TLSConnectionFactory(m_sslFactory, m_factories->getConnectionFactory());
 
			m_conn = m_factories->getConnectionFactory()->createConnection();
 
			m_conn->onDataRead.connect(boost::bind(&YahooPlugin::_handleDataRead, this, _1));
 
			m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
 

	
 
			LOG4CXX_INFO(logger, "Starting the plugin.");
 
		}
 

	
 
		// NetworkPlugin uses this method to send the data to networkplugin server
 
		void sendData(const std::string &string) {
 
			m_conn->write(Swift::createSafeByteArray(string));
 
		}
 

	
 
		// This method has to call handleDataRead with all received data from network plugin server
 
		void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
 
			std::string d(data->begin(), data->end());
 
			handleDataRead(d);
 
		}
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
			YahooLocalAccount *account = new YahooLocalAccount(user, legacyName, password);
 
			m_users[user] = account;
 
			m_ids[account->id] = user;
 

	
 
			LOG4CXX_INFO(logger, user << ": Logging in the user as " << legacyName << " with id=" << account->id);
 
			account->login();
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			YahooLocalAccount *account = m_users[user];
 
			if (account) {
 
				yahoo_logoff(account->id);
 
				m_ids.erase(account->id);
 
				m_users.erase(user);
 
				delete account;
 
			}
 
		}
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "") {
 
			YahooLocalAccount *account = m_users[user];
 
			if (account) {
 
				LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ": " << message << ".");
 
				yahoo_send_im(account->id, NULL, legacyName.c_str(), message.c_str(), 0, 0);
 
				_yahoo_write_ready(account);
 
			}
 
		}
 

	
 
		void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
 
			LOG4CXX_INFO(logger, user << ": Added buddy " << buddyName << ".");
 
			handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
 
		}
 

	
 
		void _avatar_fetched(HTTPFetch *fetch, int account_id, unsigned int id, const std::string &img) {
 
			handleVCard(m_ids[account_id], id, "", "", "", img);
 
			delete fetch;
 
		}
 

	
 
		void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
 
			YahooLocalAccount *account = m_users[user];
 
			if (!account) {
 
				return;
 
			}
 

	
 
			if (account->urls.find(legacyName) == account->urls.end()) {
 
				return;
 
			}
 

	
 
			HTTPFetch *fetch = new HTTPFetch(&m_boostIOServiceThread, m_factories->getConnectionFactory());
 
			fetch->onURLFetched.connect(boost::bind(&YahooPlugin::_avatar_fetched, this, fetch, account->id, id, _1));
 
			fetch->fetchURL(account->urls[legacyName]);
 
		}
 

	
 
		void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
 

	
 
		}
 

	
 
		YahooLocalAccount *getAccount(int id) {
 
			return m_users[m_ids[id]];
 
		}
 

	
 
		void _yahoo_remove_account(YahooLocalAccount *account) {
 
			m_ids.erase(account->id);
 
			m_users.erase(account->user);
 
			delete account;
 
		}
 

	
 
		void _yahoo_connect_finished(YahooLocalAccount *account, yahoo_connect_callback callback, void *data, int conn_tag, bool error) {
 
			currently_writting_account = account;
 
			if (error) {
 
				LOG4CXX_ERROR(logger, account->user << ": Connection error!");
 
				callback(NULL, 0, data);
 
// 				np->handleDisconnected(user, 0, "Connection error.");
 
			}
 
			else {
 
				LOG4CXX_INFO(logger, account->user << ": Connected");
 
				// We will have dangling pointer here, but we can't pass boost::shared_ptr here...
 
				callback((void *) conn_tag, 0, data);
 
			}
 
		}
 

	
 
		void _yahoo_write_ready(YahooLocalAccount *account) {
 
			// Find all WRITE handlers and inform that they really can write.
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers.begin(); it != account->handlers.end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_WRITE && !it->second->remove_later) {
 
					it->second->ready();
 
				}
 
			}
 
		}
 

	
 
		void _yahoo_data_read(YahooLocalAccount *account, int conn_tag, boost::shared_ptr<Swift::SafeByteArray> data) {
 
			std::string d(data->begin(), data->end());
 

	
 
			// Find the handler that handles READing for this conn_tag
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_READ && !it->second->remove_later) {
 
					std::string cpy(d);
 
					it->second->ready(&cpy);
 

	
 
					// Look like libyahoo2 needs to be informed it can write to socket after the read
 
					// even we have informed it before...
 
					_yahoo_write_ready(account);
 
					break;
 
				}
 
			}
 

	
 
			account->removeOldHandlers();
 
		}
 

	
 
		void _yahoo_data_written(YahooLocalAccount *account, int conn_tag) {
 
			LOG4CXX_INFO(logger, "data written");
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_WRITE) {
 
					it->second->ready();
 
				}
 
			}
 

	
 
			account->removeOldHandlers();
 
		}
 

	
 
		void _yahoo_disconnected(YahooLocalAccount *account, int conn_tag, const boost::optional<Swift::Connection::Error> &error) {
 
			for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
 
				if (it->second->cond == YAHOO_INPUT_READ && !it->second->remove_later) {
 
					std::string cpy;
 
					it->second->ready(&cpy);
 
					_yahoo_write_ready(account);
 
					break;
 
				}
 
			}
 

	
 
			account->removeConn(conn_tag);
 
		}
 

	
 
		int _yahoo_connect_async(int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl) {
 
			YahooLocalAccount *account = getAccount(id);
 
			if (!account) {
 
				LOG4CXX_ERROR(logger, "Unknown account id=" << id);
 
				return -1;
 
			}
 

	
 
			boost::asio::ip::tcp::resolver resolver(*m_boostIOServiceThread.getIOService());
 
			boost::asio::ip::tcp::resolver::query query(host, "");
 
			boost::asio::ip::address address;
 
			for(boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); i != boost::asio::ip::tcp::resolver::iterator(); ++i) {
 
				boost::asio::ip::tcp::endpoint end = *i;
 
				address = end.address();
 
				break;
 
			}
 

	
 
			LOG4CXX_INFO(logger, m_ids[id] << ": Connecting " << host << ":" << port);
 
			int tag = account->conn_tag++;
 
			if (use_ssl) {
 
				account->conns[tag] = m_tlsFactory->createConnection();
 
			}
 
			else {
 
				account->conns[tag] = m_factories->getConnectionFactory()->createConnection();
 
			}
 
			account->conns[tag]->onConnectFinished.connect(boost::bind(&YahooPlugin::_yahoo_connect_finished, this, account, callback, data, tag, _1));
 
			account->conns[tag]->onDisconnected.connect(boost::bind(&YahooPlugin::_yahoo_disconnected, this, account, tag, _1));
 
			account->conns[tag]->onDataRead.connect(boost::bind(&YahooPlugin::_yahoo_data_read, this, account, tag, _1));
 
			account->conns[tag]->onDataWritten.connect(boost::bind(&YahooPlugin::_yahoo_data_written, this, account, tag));
 
			account->conns[tag]->connect(Swift::HostAddressPort(Swift::HostAddress(address), port));
 
			return tag;
 
		}
 

	
 
	private:
 
		Config *config;
 
		std::map<std::string, YahooLocalAccount *> m_users;
 
		std::map<int, std::string> m_ids;
 
};
 

	
 
static void spectrum_sigchld_handler(int sig)
 
{
 
	int status;
 
	pid_t pid;
 

	
 
	do {
 
		pid = waitpid(-1, &status, WNOHANG);
 
	} while (pid != 0 && pid != (pid_t)-1);
 

	
 
	if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
 
		char errmsg[BUFSIZ];
 
		snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
 
		perror(errmsg);
 
	}
 
}
 

	
 
static void ext_yahoo_got_conf_invite(int id, const char *me, const char *who, const char *room, const char *msg, YList *members) {
 
}
 

	
 
static void ext_yahoo_conf_userdecline(int id, const char *me, const char *who, const char *room, const char *msg) {
 
}
 

	
 
static void ext_yahoo_conf_userjoin(int id, const char *me, const char *who, const char *room) {
 
}
 

	
 
static void ext_yahoo_conf_userleave(int id, const char *me, const char *who, const char *room) {
 
}
 

	
 
static void ext_yahoo_conf_message(int id, const char *me, const char *who, const char *room, const char *msg, int utf8) {
 
}
 

	
 
static void ext_yahoo_chat_cat_xml(int id, const char *xml)  {
 
}
 

	
 
static void ext_yahoo_chat_join(int id, const char *me, const char *room, const char * topic, YList *members, void *fd) {
 
}
 

	
 
static void ext_yahoo_chat_userjoin(int id, const char *me, const char *room, struct yahoo_chat_member *who) {
 
}
 

	
 
static void ext_yahoo_chat_userleave(int id, const char *me, const char *room, const char *who) {
 
}
 

	
 
static void ext_yahoo_chat_message(int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8) {
 
}
 

	
 
static void ext_yahoo_status_changed(int id, const char *who, int stat, const char *msg, int away, int idle, int mobile) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, account->user << ": " << who << " status changed");
 

	
 
	pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
 
	switch (stat) {
 
		case YAHOO_STATUS_AVAILABLE:
 
			status = pbnetwork::STATUS_ONLINE;
 
			break;
 
		case YAHOO_STATUS_NOTATHOME:
 
		case YAHOO_STATUS_NOTATDESK:
 
		case YAHOO_STATUS_NOTINOFFICE:
 
		case YAHOO_STATUS_ONPHONE:
 
		case YAHOO_STATUS_ONVACATION:
 
		case YAHOO_STATUS_OUTTOLUNCH:
 
		case YAHOO_STATUS_STEPPEDOUT:
 
			status = pbnetwork::STATUS_AWAY;
 
			break;
 
		case YAHOO_STATUS_BRB:
 
			status = pbnetwork::STATUS_XA;
 
			break;
 
		case YAHOO_STATUS_BUSY:
 
			status = pbnetwork::STATUS_DND;
 
			break;
 
		case YAHOO_STATUS_OFFLINE:
 
			status = pbnetwork::STATUS_NONE;
 
			break;
 
		default:
 
			status = pbnetwork::STATUS_ONLINE;
 
			break;
 
	}
 

	
 
	yahoo_buddyicon_request(id, who);
 
	np->_yahoo_write_ready(account);
 

	
 
	np->handleBuddyChanged(account->user, who, "", std::vector<std::string>(), status, msg ? msg : "");
 
}
 

	
 
static void ext_yahoo_got_buddies(int id, YList * buds) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, account->user << ": Got buddy list");
 
	for(; buds; buds = buds->next) {
 
		struct yahoo_buddy *bud = (struct yahoo_buddy *) buds->data;
 

	
 
		std::vector<std::string> groups;
 
		groups.push_back(bud->group);
 
		np->handleBuddyChanged(account->user, bud->id, bud->real_name ? bud->real_name : "", groups, pbnetwork::STATUS_NONE);
 
	}
 

	
 
// 	yahoo_set_away(id, YAHOO_STATUS_AVAILABLE, "", 1);
 
	np->_yahoo_write_ready(account);
 
	np->handleConnected(account->user);
 
}
 

	
 
static void ext_yahoo_got_ignore(int id, YList * igns)
 
{
 
}
 

	
 
static void ext_yahoo_got_buzz(int id, const char *me, const char *who, long tm) {
 
}
 

	
 
static void ext_yahoo_got_im(int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	np->handleMessage(account->user, who, msg);
 
}
 

	
 
static void ext_yahoo_rejected(int id, const char *who, const char *msg) {
 
}
 

	
 
static void ext_yahoo_contact_added(int id, const char *myid, const char *who, const char *msg) {
 
}
 

	
 
static void ext_yahoo_typing_notify(int id, const char* me, const char *who, int stat) {
 
}
 

	
 
static void ext_yahoo_game_notify(int id, const char *me, const char *who, int stat, const char *msg)
 
{
 
}
 

	
 
static void ext_yahoo_mail_notify(int id, const char *from, const char *subj, int cnt) {
 
}
 

	
 
static void ext_yahoo_got_webcam_image(int id, const char *who, const unsigned char *image, unsigned int image_size, unsigned int real_size, unsigned int timestamp) {
 
}
 

	
 
static void ext_yahoo_webcam_viewer(int id, const char *who, int connect) {
 
}
 

	
 
static void ext_yahoo_webcam_closed(int id, const char *who, int reason) {
 
}
 

	
 
static void ext_yahoo_webcam_data_request(int id, int send) {
 
}
 

	
 
static void ext_yahoo_webcam_invite(int id, const char *me, const char *from) {
 
}
 

	
 
static void ext_yahoo_webcam_invite_reply(int id, const char *me, const char *from, int accept) {
 
}
 

	
 
static void ext_yahoo_system_message(int id, const char *me, const char *who, const char *msg) {
 
}
 

	
 
static void ext_yahoo_got_cookies(int id) {
 
}
 

	
 
static void ext_yahoo_login_response(int id, int succ, const char *url) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	if (succ == YAHOO_LOGIN_OK) {
 
		account->status = yahoo_current_status(id);
 
		// We will fire handleConnected in Got Buddy List.
 
		return;
 
	}
 
	else if (succ == YAHOO_LOGIN_UNAME) {
 
		np->handleDisconnected(account->user, 0, "Could not log into Yahoo service - username not recognised.  Please verify that your username is correctly typed.");
 
	}
 
	else if (succ == YAHOO_LOGIN_PASSWD) {
 
		np->handleDisconnected(account->user, 0, "Could not log into Yahoo service - password incorrect.  Please verify that your password is correctly typed.");
 
	}
 
	else if (succ == YAHOO_LOGIN_LOCK) {
 
		np->handleDisconnected(account->user, 0, std::string("Could not log into Yahoo service.  Your account has been locked. Visit ") + url + " to reactivate it.");
 
	}
 
	else if (succ == YAHOO_LOGIN_DUPL) {
 
		np->handleDisconnected(account->user, 0, "You have been logged out of the yahoo service, possibly due to a duplicate login.");
 
	}
 
	else if (succ == YAHOO_LOGIN_SOCK) {
 
		np->handleDisconnected(account->user, 0, "The server closed the socket.");
 
	}
 
	else {
 
		np->handleDisconnected(account->user, 0, "Could not log in, unknown reason.");
 
	}
 

	
 
	np->handleLogoutRequest(account->user, "");
 
}
 

	
 
static void ext_yahoo_error(int id, const char *_err, int fatal, int num) {
 
	std::string err(_err);
 
	std::string msg("Yahoo Error: ");
 
	msg += err + " - ";
 
	switch(num) {
 
		case E_UNKNOWN:
 
			msg += "unknown error " + err;
 
			break;
 
		case E_CUSTOM:
 
			msg += "custom error " + err;
 
			break;
 
		case E_CONFNOTAVAIL:
 
			msg += err + " is not available for the conference";
 
			break;
 
		case E_IGNOREDUP:
 
			msg += err + " is already ignored";
 
			break;
 
		case E_IGNORENONE:
 
			msg += err +" is not in the ignore list";
 
			break;
 
		case E_IGNORECONF:
 
			msg += err + " is in buddy list - cannot ignore ";
 
			break;
 
		case E_SYSTEM:
 
			msg += "system error " + err;
 
			break;
 
		case E_CONNECTION:
 
			msg += err + "server connection error %s";
 
			break;
 
	}
 
	LOG4CXX_ERROR(logger, msg);
 

	
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	if(fatal) {
 
		np->handleDisconnected(account->user, 0, msg);
 
		np->handleLogoutRequest(account->user, "");
 
	}
 
}
 

	
 
static int ext_yahoo_connect(const char *host, int port) {
 
	return -1;
 
}
 

	
 
static int ext_yahoo_add_handler(int id, void *fd, yahoo_input_condition cond, void *data) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return -1;
 
	}
 

	
 
	int conn_tag = (unsigned long) fd;
 
	YahooHandler *handler = new YahooHandler(account, conn_tag, account->handler_tag++, data, cond);
 
	account->addHandler(handler);
 

	
 
	// We are ready to write right now, so why not...
 
	handler->ready();
 

	
 
	return handler->handler_tag;
 
}
 

	
 
static void ext_yahoo_remove_handler(int id, int tag) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	if (account->handlers.find(tag) == account->handlers.end()) {
 
		return;
 
	}
 

	
 
	YahooHandler *handler = account->handlers[tag];
 
	handler->remove_later = true;
 
}
 

	
 
static int ext_yahoo_write(void *fd, char *buf, int len) {
 
	int conn_tag = (unsigned long) fd;
 
	YahooLocalAccount *account = currently_writting_account;
 

	
 
	std::string string(buf, len);
 
	account->conns[conn_tag]->write(Swift::createSafeByteArray(string));
 

	
 
	return len;
 
}
 

	
 
static int ext_yahoo_read(void *fd, char *buf, int len) {
 
	if (currently_read_data->size() < len) {
 
		len = currently_read_data->size();
 
	}
 
	memcpy(buf, currently_read_data->c_str(), len);
 
	currently_read_data->erase(0, len);
 
	return len;
 
}
 

	
 
static void ext_yahoo_close(void *fd) {
 
	// No need to do anything here. We close it properly in _yahoo_disconnected(...);
 
}
 

	
 
static int ext_yahoo_connect_async(int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl) {
 
	return np->_yahoo_connect_async(id, host, port, callback, data, use_ssl);
 
}
 

	
 
static void ext_yahoo_got_file(int id, const char *me, const char *who, const char *msg, const char *fname, unsigned long fesize, char *trid) {
 
}
 

	
 
static void ext_yahoo_file_transfer_done(int id, int response, void *data) {
 
}
 

	
 
static char *ext_yahoo_get_ip_addr(const char *domain) {
 
	return NULL;
 
}
 

	
 
static void ext_yahoo_got_ft_data(int id, const unsigned char *in, int count, void *data) {
 
}
 

	
 
static void ext_yahoo_got_identities(int id, YList * ids) {
 
}
 

	
 
static void ext_yahoo_chat_yahoologout(int id, const char *me) {
 
}
 

	
 
static void ext_yahoo_chat_yahooerror(int id, const char *me) {
 
}
 

	
 
static void ext_yahoo_got_ping(int id, const char *errormsg){
 
}
 

	
 
static void ext_yahoo_got_search_result(int id, int found, int start, int total, YList *contacts) {
 
}
 

	
 
static void ext_yahoo_got_buddyicon_checksum(int id, const char *a, const char *b, int checksum) {
 
	LOG4CXX_INFO(logger, "got buddyicon_checksum");
 
}
 

	
 
static void ext_yahoo_got_buddy_change_group(int id, const char *me, const char *who, const char *old_group, const char *new_group) {
 
}
 

	
 
static void ext_yahoo_got_buddyicon(int id, const char *me, const char *who, const char *url, int checksum) {
 
	YahooLocalAccount *account = np->getAccount(id);
 
	if (!account) {
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, account->user << ": got buddyicon of " << who);
 
	account->urls[who] = url;
 
}
 

	
 
static void ext_yahoo_buddyicon_uploaded(int id, const char *url) {
 
}
 

	
 
static void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who) {
 
	LOG4CXX_INFO(logger, "got buddyicon_request");
 
}
 

	
 
static int ext_yahoo_log(const char *fmt,...)
 
{
 
	static char log[8192];
 
	static std::string buffered;
 
	va_list ap;
 

	
 
	va_start(ap, fmt);
 

	
 
	vsnprintf(log, 8191, fmt, ap);
 
	buffered += log;
 
	if (buffered.find('\n') != std::string::npos) {
 
		buffered.erase(buffered.find('\n'), 1);
 
		LOG4CXX_INFO(logger, buffered);
 
		buffered.clear();
 
	}
 
	fflush(stderr);
 
	va_end(ap);
 
	return 0;
 
}
 

	
 
static void register_callbacks()
 
{
 
	static struct yahoo_callbacks yc;
 

	
 
	yc.ext_yahoo_login_response = ext_yahoo_login_response;
 
	yc.ext_yahoo_got_buddies = ext_yahoo_got_buddies;
 
	yc.ext_yahoo_got_ignore = ext_yahoo_got_ignore;
 
	yc.ext_yahoo_got_identities = ext_yahoo_got_identities;
 
	yc.ext_yahoo_got_cookies = ext_yahoo_got_cookies;
 
	yc.ext_yahoo_status_changed = ext_yahoo_status_changed;
 
	yc.ext_yahoo_got_im = ext_yahoo_got_im;
 
	yc.ext_yahoo_got_buzz = ext_yahoo_got_buzz;
 
	yc.ext_yahoo_got_conf_invite = ext_yahoo_got_conf_invite;
 
	yc.ext_yahoo_conf_userdecline = ext_yahoo_conf_userdecline;
 
	yc.ext_yahoo_conf_userjoin = ext_yahoo_conf_userjoin;
 
	yc.ext_yahoo_conf_userleave = ext_yahoo_conf_userleave;
 
	yc.ext_yahoo_conf_message = ext_yahoo_conf_message;
 
	yc.ext_yahoo_chat_cat_xml = ext_yahoo_chat_cat_xml;
 
	yc.ext_yahoo_chat_join = ext_yahoo_chat_join;
 
	yc.ext_yahoo_chat_userjoin = ext_yahoo_chat_userjoin;
 
	yc.ext_yahoo_chat_userleave = ext_yahoo_chat_userleave;
 
	yc.ext_yahoo_chat_message = ext_yahoo_chat_message;
 
	yc.ext_yahoo_chat_yahoologout = ext_yahoo_chat_yahoologout;
 
	yc.ext_yahoo_chat_yahooerror = ext_yahoo_chat_yahooerror;
 
	yc.ext_yahoo_got_webcam_image = ext_yahoo_got_webcam_image;
 
	yc.ext_yahoo_webcam_invite = ext_yahoo_webcam_invite;
 
	yc.ext_yahoo_webcam_invite_reply = ext_yahoo_webcam_invite_reply;
 
	yc.ext_yahoo_webcam_closed = ext_yahoo_webcam_closed;
 
	yc.ext_yahoo_webcam_viewer = ext_yahoo_webcam_viewer;
 
	yc.ext_yahoo_webcam_data_request = ext_yahoo_webcam_data_request;
 
	yc.ext_yahoo_got_file = ext_yahoo_got_file;
 
	yc.ext_yahoo_got_ft_data = ext_yahoo_got_ft_data;
 
	yc.ext_yahoo_get_ip_addr = ext_yahoo_get_ip_addr;
 
	yc.ext_yahoo_file_transfer_done = ext_yahoo_file_transfer_done;
 
	yc.ext_yahoo_contact_added = ext_yahoo_contact_added;
 
	yc.ext_yahoo_rejected = ext_yahoo_rejected;
 
	yc.ext_yahoo_typing_notify = ext_yahoo_typing_notify;
 
	yc.ext_yahoo_game_notify = ext_yahoo_game_notify;
 
	yc.ext_yahoo_mail_notify = ext_yahoo_mail_notify;
 
	yc.ext_yahoo_got_search_result = ext_yahoo_got_search_result;
 
	yc.ext_yahoo_system_message = ext_yahoo_system_message;
 
	yc.ext_yahoo_error = ext_yahoo_error;
 
	yc.ext_yahoo_log = ext_yahoo_log;
 
	yc.ext_yahoo_add_handler = ext_yahoo_add_handler;
 
	yc.ext_yahoo_remove_handler = ext_yahoo_remove_handler;
 
	yc.ext_yahoo_connect = ext_yahoo_connect;
 
	yc.ext_yahoo_connect_async = ext_yahoo_connect_async;
 
	yc.ext_yahoo_read = ext_yahoo_read;
 
	yc.ext_yahoo_write = ext_yahoo_write;
 
	yc.ext_yahoo_close = ext_yahoo_close;
 
	yc.ext_yahoo_got_buddyicon = ext_yahoo_got_buddyicon;
 
	yc.ext_yahoo_got_buddyicon_checksum = ext_yahoo_got_buddyicon_checksum;
 
	yc.ext_yahoo_buddyicon_uploaded = ext_yahoo_buddyicon_uploaded;
 
	yc.ext_yahoo_got_buddyicon_request = ext_yahoo_got_buddyicon_request;
 
	yc.ext_yahoo_got_ping = ext_yahoo_got_ping;
 
	yc.ext_yahoo_got_buddy_change_group = ext_yahoo_got_buddy_change_group;
 

	
 
	yahoo_register_callbacks(&yc);
 
}
 

	
 
int main (int argc, char* argv[]) {
 
	std::string host;
 
	int port;
 

	
 
#ifndef _WIN32
 
	if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
 
		std::cout << "SIGCHLD handler can't be set\n";
 
		return -1;
 
	}
 
#endif
 

	
 
	std::string error;
 
	Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
 
	if (cfg == NULL) {
 
		std::cerr << error;
 
		return 1;
 
	}
 

	
 
	Logging::initBackendLogging(cfg);
 

	
 
	register_callbacks();
 
	yahoo_set_log_level(YAHOO_LOG_DEBUG);
 

	
 
	Swift::SimpleEventLoop eventLoop;
 
	loop_ = &eventLoop;
 
	np = new YahooPlugin(cfg, &eventLoop, host, port);
 
	loop_->run();
 

	
 
	return 0;
 
}
backends/libyahoo2/sample_client.example
Show inline comments
 
new file 100644
 
/*
 
 * sample yahoo client based on libyahoo2
 
 *
 
 * libyahoo2 is available at http://libyahoo2.sourceforge.net/
 
 *
 
 * $Revision: 373 $
 
 * $Date: 2010-06-02 13:55:25 -0700 (Wed, 02 Jun 2010) $
 
 * 
 
 * Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
 
 * Copyright (C) 2009, Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
 
 *
 
 * 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
 
 *
 
 */
 

	
 
#if HAVE_CONFIG_H
 
# include <config.h>
 
#endif
 
#ifndef _WIN32
 
#include <netdb.h>
 
#include <sys/time.h>
 
#endif
 
#include <sys/types.h>
 
#ifndef _WIN32
 
#include <sys/socket.h>
 
#include <netinet/in.h>
 
#include <arpa/inet.h>
 

	
 
#include <termios.h>
 
#endif
 
#include <stdio.h>
 
#include <stdarg.h>
 
#include <stdlib.h>
 
#include <string.h>
 
#include <ctype.h>
 
#include <time.h>
 
#include <sys/stat.h>
 
#include <fcntl.h>
 
#include <errno.h>
 
#include <openssl/ssl.h>
 
#if HAVE_UNISTD_H
 
#include <unistd.h>
 
#endif
 

	
 
/* Get these from http://libyahoo2.sourceforge.net/ */
 
#include <yahoo2.h>
 
#include <yahoo2_callbacks.h>
 
#include "yahoo_util.h"
 

	
 
#ifndef _WIN32
 
int fileno(FILE * stream);
 
#endif
 

	
 
#define MAX_PREF_LEN 255
 

	
 
static char *local_host = NULL;
 

	
 
static int do_mail_notify = 0;
 
static int do_yahoo_debug = 0;
 
static int ignore_system = 0;
 
static int do_typing_notify = 1;
 
static int accept_webcam_viewers = 1;
 
static int send_webcam_images = 0;
 
static int webcam_direction = YAHOO_WEBCAM_DOWNLOAD;
 
static time_t curTime = 0;
 
static time_t pingTimer = 0;
 
static time_t webcamTimer = 0;
 
static double webcamStart = 0;
 

	
 
/* id of the webcam connection (needed for uploading) */
 
static int webcam_id = 0;
 

	
 
static int poll_loop=1;
 

	
 
static void register_callbacks();
 

	
 
typedef struct {
 
	char yahoo_id[255];
 
	char password[255];
 
	int id;
 
	int fd;
 
	int status;
 
	char *msg;
 
} yahoo_local_account;
 

	
 
typedef struct {
 
	char yahoo_id[255];
 
	char name[255];
 
	int status;
 
	int away;
 
	char *msg;
 
	char group[255];
 
} yahoo_account;
 

	
 
typedef struct {
 
	int id;
 
	char *label;
 
} yahoo_idlabel;
 

	
 
typedef struct {
 
	int id;
 
	char *who;
 
} yahoo_authorize_data;
 

	
 
yahoo_idlabel yahoo_status_codes[] = {
 
	{YAHOO_STATUS_AVAILABLE, "Available"},
 
	{YAHOO_STATUS_BRB, "BRB"},
 
	{YAHOO_STATUS_BUSY, "Busy"},
 
	{YAHOO_STATUS_NOTATHOME, "Not Home"},
 
	{YAHOO_STATUS_NOTATDESK, "Not at Desk"},
 
	{YAHOO_STATUS_NOTINOFFICE, "Not in Office"},
 
	{YAHOO_STATUS_ONPHONE, "On Phone"},
 
	{YAHOO_STATUS_ONVACATION, "On Vacation"},
 
	{YAHOO_STATUS_OUTTOLUNCH, "Out to Lunch"},
 
	{YAHOO_STATUS_STEPPEDOUT, "Stepped Out"},
 
	{YAHOO_STATUS_INVISIBLE, "Invisible"},
 
	{YAHOO_STATUS_IDLE, "Idle"},
 
	{YAHOO_STATUS_OFFLINE, "Offline"},
 
	{YAHOO_STATUS_CUSTOM, "[Custom]"},
 
	{YPACKET_STATUS_NOTIFY, "Notify"},
 
	{0, NULL}
 
};
 

	
 
static void ext_yahoo_close(void *fd);
 

	
 
char * yahoo_status_code(enum yahoo_status s)
 
{
 
	int i;
 
	for(i=0; yahoo_status_codes[i].label; i++)
 
		if(yahoo_status_codes[i].id == s)
 
			return yahoo_status_codes[i].label;
 
	return "Unknown";
 
}
 

	
 
#define YAHOO_DEBUGLOG ext_yahoo_log
 

	
 
static int ext_yahoo_log(const char *fmt,...)
 
{
 
	va_list ap;
 

	
 
	va_start(ap, fmt);
 

	
 
	vfprintf(stderr, fmt, ap);
 
	fflush(stderr);
 
	va_end(ap);
 
	return 0;
 
}
 

	
 
#define LOG(x) if(do_yahoo_debug) { YAHOO_DEBUGLOG("%s:%d: ", __FILE__, __LINE__); \
 
	YAHOO_DEBUGLOG x; \
 
	YAHOO_DEBUGLOG("\n"); }
 

	
 
#define WARNING(x) if(do_yahoo_debug) { YAHOO_DEBUGLOG("%s:%d: warning: ", __FILE__, __LINE__); \
 
	YAHOO_DEBUGLOG x; \
 
	YAHOO_DEBUGLOG("\n"); }
 

	
 
#define print_message(x) { printf x; printf("\n"); }
 

	
 
static yahoo_local_account * ylad = NULL;
 
static YList * buddies = NULL;
 

	
 
static int expired(time_t timer)
 
{
 
	if (timer && curTime >= timer)
 
		return 1;
 

	
 
	return 0;
 
}
 

	
 
static void rearm(time_t *timer, int seconds)
 
{
 
	time(timer);
 
	*timer += seconds;
 
}
 

	
 
#ifndef _WIN32
 
FILE *popen(const char *command, const char *type);
 
int pclose(FILE *stream);
 
int gethostname(char *name, size_t len);
 
#endif
 

	
 
static char * get_local_addresses()
 
{
 
	static char addresses[1024];
 
	char buff[1024];
 
	struct hostent * hn;
 
#ifndef _WIN32
 
	char gateway[16];
 
	char  * c;
 
	int i;
 
	FILE * f;
 
	f = popen("netstat -nr", "r");
 
	if(!f)
 
			goto IP_TEST_2;
 
	while( fgets(buff, sizeof(buff), f)  != NULL ) {
 
			c = strtok( buff, " " );
 
			if( (strstr(c, "default") || strstr(c,"0.0.0.0") ) &&
 
							!strstr(c, "127.0.0" ) )
 
					break;
 
	}
 
	c = strtok( NULL, " " );
 
	pclose(f);
 

	
 
	strncpy(gateway,c, 16);
 

	
 

	
 

	
 
	for(i = strlen(gateway); gateway[i] != '.'; i-- )
 
		gateway[i] = 0;
 

	
 
	gateway[i] = 0;
 

	
 
	for(i = strlen(gateway); gateway[i] != '.'; i-- )
 
		gateway[i] = 0;
 

	
 
	f = popen("/sbin/ifconfig -a", "r");
 
	if(!f)
 
		goto IP_TEST_2;
 

	
 
	while( fgets(buff, sizeof(buff), f) != NULL ) {
 
		if( strstr(buff, "inet") && strstr(buff,gateway) )
 
			break;
 
	}
 
	pclose(f);
 

	
 
	c = strtok( buff, " " );
 
	c = strtok( NULL, " " );
 

	
 
	strncpy ( addresses, c, sizeof(addresses) );
 
	c = strtok(addresses, ":" );
 
	strncpy ( buff, c, sizeof(buff) );
 
	if((c=strtok(NULL, ":")))
 
		strncpy( buff, c, sizeof(buff) );
 

	
 
	strncpy(addresses, buff, sizeof(addresses));
 

	
 
	return addresses;
 
		
 
		
 
IP_TEST_2:
 
#endif /* _WIN32 */
 

	
 
	gethostname(buff,sizeof(buff));
 

	
 
	hn = gethostbyname(buff);
 
	if(hn)
 
		strncpy(addresses, inet_ntoa( *((struct in_addr*)hn->h_addr)), sizeof(addresses) );
 
	else
 
		addresses[0] = 0;
 

	
 
	return addresses;
 
}
 

	
 
static double get_time()
 
{
 
#ifndef _WIN32
 
	struct timeval ct;
 
	gettimeofday(&ct, 0);
 

	
 
	/* return time in milliseconds */
 
	return (ct.tv_sec * 1E3 + ct.tv_usec / 1E3);
 
#else
 
	return timeGetTime();
 
#endif
 
}
 

	
 
static int yahoo_ping_timeout_callback()
 
{
 
	print_message(("Sending a keep alive message"));
 
	yahoo_keepalive(ylad->id);
 
	rearm(&pingTimer, 600);
 
	return 1;
 
}
 

	
 
static int yahoo_webcam_timeout_callback(int id)
 
{
 
	static unsigned image_num = 0;
 
	unsigned char *image = NULL;
 
	unsigned int length = 0;
 
	unsigned int timestamp = get_time() - webcamStart;
 
	char fname[1024];
 
	FILE *f_image = NULL;
 
	struct stat s_image;
 

	
 
	if (send_webcam_images)
 
	{
 
		sprintf(fname, "images/image_%.3d.jpc", image_num++);
 
		if (image_num > 999) image_num = 0;
 
		if (stat(fname, &s_image) == -1)
 
			return -1;
 
		length = s_image.st_size;
 
		image = y_new0(unsigned char, length);
 

	
 
		if ((f_image = fopen(fname, "r")) != NULL) {
 
			fread(image, length, 1, f_image);
 
			fclose(f_image);
 
		} else {
 
			printf("Error reading from %s\n", fname);
 
		}
 
	}
 

	
 
	print_message(("Sending a webcam image (%d bytes)", length));
 
	yahoo_webcam_send_image(id, image, length, timestamp);
 
	FREE(image);
 
	rearm(&webcamTimer, 2);
 
	return 1;
 
}
 

	
 
YList * conferences = NULL;
 
typedef struct {
 
	int id;
 
	char * me;
 
	char * room_name;
 
	char * host;
 
	YList * members;
 
	int joined;
 
} conf_room;
 

	
 
static const char * get_buddy_name(const char * yid)
 
{
 
	YList * b;
 
	for (b = buddies; b; b = b->next) {
 
		yahoo_account * ya = b->data;
 
		if(!strcmp(yid, ya->yahoo_id))
 
			return ya->name&&*ya->name?ya->name:ya->yahoo_id;
 
	}
 

	
 
	return yid;
 
}
 

	
 
static conf_room * find_conf_room_by_name_and_id(int id, const char * me, const char * name)
 
{
 
	YList * l;
 
	for(l = conferences; l; l=l->next) {
 
		conf_room * cr = l->data;
 
		if(cr->id == id && !strcmp(name, cr->room_name) && (me == NULL || cr->me == NULL || !strcmp(me, cr->me))) {
 
			return cr;
 
		}
 
	}
 

	
 
	return NULL;
 
}
 

	
 
static void ext_yahoo_got_conf_invite(int id, const char *me, const char *who, const char *room, const char *msg, YList *members)
 
{
 
	conf_room * cr = y_new0(conf_room, 1);
 
	cr->room_name = strdup(room);
 
	cr->me = strdup(me);
 
	cr->host = strdup(who);
 
	cr->members = members;
 
	cr->id = id;
 

	
 
	conferences = y_list_append(conferences, cr);
 

	
 
	print_message(("%s has invited you [%s] to a conference: %s\n"
 
				"with the message: %s",
 
				who, me, room, msg));
 

	
 
	for(; members; members=members->next)
 
		print_message(("\t%s", (char *)members->data));
 
	
 
}
 
static void ext_yahoo_conf_userdecline(int id, const char *me, const char *who, const char *room, const char *msg)
 
{
 
	YList * l;
 
	/* TODO: probably have to use the me arg to find the room */
 
	conf_room * cr = find_conf_room_by_name_and_id(id, me, room);
 
	
 
	if(cr)
 
	for(l = cr->members; l; l=l->next) {
 
		char * w = l->data;
 
		if(!strcmp(w, who)) {
 
			FREE(l->data);
 
			cr->members = y_list_remove_link(cr->members, l);
 
			y_list_free_1(l);
 
			break;
 
		}
 
	}
 

	
 
	print_message(("%s declined the invitation from %s to %s\n"
 
				"with the message: %s", who, me, room, msg));
 
}
 

	
 
static void ext_yahoo_conf_userjoin(int id, const char *me, const char *who, const char *room)
 
{
 
	conf_room * cr = find_conf_room_by_name_and_id(id, me, room);
 
	if(cr) {
 
	YList * l = NULL;
 
	for(l = cr->members; l; l=l->next) {
 
		char * w = l->data;
 
		if(!strcmp(w, who))
 
			break;
 
	}
 
	if(!l)
 
		cr->members = y_list_append(cr->members, strdup(who));
 
	}
 

	
 
	print_message(("%s joined the conference %s [%s]", who, room, me));
 

	
 
}
 

	
 
static void ext_yahoo_conf_userleave(int id, const char *me, const char *who, const char *room)
 
{
 
	YList * l;
 
	conf_room * cr = find_conf_room_by_name_and_id(id, me, room);
 
	
 
	if(cr)
 
	for(l = cr->members; l; l=l->next) {
 
		char * w = l->data;
 
		if(!strcmp(w, who)) {
 
			FREE(l->data);
 
			cr->members = y_list_remove_link(cr->members, l);
 
			y_list_free_1(l);
 
			break;
 
		}
 
	}
 

	
 
	print_message(("%s left the conference %s [%s]", who, room, me));
 
}
 

	
 
static void ext_yahoo_conf_message(int id, const char *me, const char *who, const char *room, const char *msg, int utf8)
 
{
 
	char * umsg = (char *)msg;
 

	
 
	if(utf8)
 
		umsg = y_utf8_to_str(msg);
 

	
 
	who = get_buddy_name(who);
 

	
 
	print_message(("%s (in %s [%s]): %s", who, room, me, umsg));
 

	
 
	if(utf8)
 
		FREE(umsg);
 
}
 

	
 
static void print_chat_member(struct yahoo_chat_member *ycm) 
 
{
 
	printf("%s (%s) ", ycm->id, ycm->alias);
 
	printf(" Age: %d Sex: ", ycm->age);
 
	if (ycm->attribs & YAHOO_CHAT_MALE) {
 
		printf("Male");
 
	} else if (ycm->attribs & YAHOO_CHAT_FEMALE) {
 
		printf("Female");
 
	} else {
 
		printf("Unknown");
 
	}
 
	if (ycm->attribs & YAHOO_CHAT_WEBCAM) {
 
		printf(" with webcam");
 
	}
 

	
 
	printf("  Location: %s", ycm->location);
 
}
 

	
 
static void ext_yahoo_chat_cat_xml(int id, const char *xml) 
 
{
 
	print_message(("%s", xml));
 
}
 

	
 
static void ext_yahoo_chat_join(int id, const char *me, const char *room, const char * topic, YList *members, void *fd)
 
{
 
	print_message(("You [%s] have joined the chatroom %s with topic %s", me, room, topic));
 

	
 
	while(members) {
 
		YList *n = members->next;
 

	
 
		printf("\t");
 
		print_chat_member(members->data);
 
		printf("\n");
 
		FREE(((struct yahoo_chat_member *)members->data)->id);
 
		FREE(((struct yahoo_chat_member *)members->data)->alias);
 
		FREE(((struct yahoo_chat_member *)members->data)->location);
 
		FREE(members->data);
 
		FREE(members);
 
		members=n;
 
	}
 
}
 

	
 
static void ext_yahoo_chat_userjoin(int id, const char *me, const char *room, struct yahoo_chat_member *who)
 
{
 
	print_chat_member(who);
 
	print_message((" joined the chatroom %s [%s]", room, me));
 
	FREE(who->id);
 
	FREE(who->alias);
 
	FREE(who->location);
 
	FREE(who);
 
}
 

	
 
static void ext_yahoo_chat_userleave(int id, const char *me, const char *room, const char *who)
 
{
 
	print_message(("%s left the chatroom %s [%s]", who, room, me));
 
}
 

	
 
static void ext_yahoo_chat_message(int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8)
 
{
 
	char * umsg = (char *)msg;
 
	char * charpos;
 

	
 
	if(utf8)
 
		umsg = y_utf8_to_str(msg);
 
	/* Remove escapes */
 
	charpos = umsg;
 
	while(*charpos) {
 
		if (*charpos == 0x1b) {
 
			*charpos = ' ';
 
		}
 
		charpos++;
 
	}
 

	
 
	if (msgtype == 2) {
 
		print_message(("(in %s [%s]) %s %s", room, me, who, umsg));
 
	} else {
 
		print_message(("(in %s [%s]) %s: %s", room, me, who, umsg));
 
	}
 

	
 
	if(utf8)
 
		FREE(umsg);
 
}
 

	
 
static void ext_yahoo_status_changed(int id, const char *who, int stat, const char *msg, int away, int idle, int mobile)
 
{
 
	yahoo_account * ya=NULL;
 
	YList * b;
 
	char buf[1024];
 

	
 
	for(b = buddies; b; b = b->next) {
 
		if(!strcmp(((yahoo_account *)b->data)->yahoo_id, who)) {
 
			ya = b->data;
 
			break;
 
		}
 
	}
 
	
 
	if (msg == NULL) {
 
		sprintf(buf, "%s", yahoo_status_code(stat));
 
	}
 
	else if (stat == YAHOO_STATUS_CUSTOM) {
 
		sprintf(buf, "%s", msg);
 
	} else {
 
		sprintf(buf, "%s: %s", yahoo_status_code(stat), msg);
 
	}
 

	
 
	if (away > 0) {
 
		char away_buf[32];
 
		sprintf(away_buf, " away[%d]", away);
 
		strcat(buf, away_buf);
 
	}
 

	
 
	if (mobile > 0) {
 
		char mobile_buf[32];
 
		sprintf(mobile_buf, " mobile[%d]", mobile);
 
		strcat(buf, mobile_buf);
 
	}
 

	
 
	if (idle > 0) {
 
		char time_buf[32];
 
		sprintf(time_buf, " idle for %d:%02d:%02d", idle/3600, (idle/60)%60, idle%60);
 
		strcat(buf, time_buf);
 
	}
 

	
 
	print_message(("%s (%s) is now %s", ya?ya->name:who, who, buf))
 

	
 
	if(ya) {
 
		ya->status = stat;
 
		ya->away = away;
 
		if(msg) {
 
			FREE(ya->msg);
 
			ya->msg = strdup(msg);
 
		}
 
	}
 
}
 

	
 
static void ext_yahoo_got_buddies(int id, YList * buds)
 
{
 
	while(buddies) {
 
		FREE(buddies->data);
 
		buddies = buddies->next;
 
		if(buddies)
 
			FREE(buddies->prev);
 
	}
 
	for(; buds; buds = buds->next) {
 
		yahoo_account *ya = y_new0(yahoo_account, 1);
 
		struct yahoo_buddy *bud = buds->data;
 
		strncpy(ya->yahoo_id, bud->id, 255);
 
		if(bud->real_name)
 
			strncpy(ya->name, bud->real_name, 255);
 
		strncpy(ya->group, bud->group, 255);
 
		ya->status = YAHOO_STATUS_OFFLINE;
 
		buddies = y_list_append(buddies, ya);
 

	
 
/*		print_message(("%s is %s", bud->id, bud->real_name));*/
 
	}
 
}
 

	
 
static void ext_yahoo_got_ignore(int id, YList * igns)
 
{
 
}
 

	
 
static void ext_yahoo_got_buzz(int id, const char *me, const char *who, long tm)
 
{
 
	who = get_buddy_name(who);
 

	
 
	printf("\a");
 
	if(tm) {
 
		char timestr[255];
 

	
 
		strncpy(timestr, ctime((time_t *)&tm), sizeof(timestr));
 
		timestr[strlen(timestr) - 1] = '\0';
 

	
 
		print_message(("[Offline message at %s to %s from %s]: **DING**",
 
				timestr, me, who))
 
	} else
 
		print_message(("[%s]%s: **DING**", me, who))
 
}
 

	
 
static void ext_yahoo_got_im(int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8)
 
{
 
	char *umsg = (char *)msg;
 

	
 
	if(stat == 2) {
 
		LOG(("Error sending message from %s to %s", me, who));
 
		return;
 
	}
 

	
 
	if(!msg)
 
		return;
 

	
 
	if(utf8)
 
		umsg = y_utf8_to_str(msg);
 
	
 
	who = get_buddy_name(who);
 

	
 
	if(tm) {
 
		char timestr[255];
 

	
 
		strncpy(timestr, ctime((time_t *)&tm), sizeof(timestr));
 
		timestr[strlen(timestr) - 1] = '\0';
 

	
 
		print_message(("[Offline message at %s to %s from %s]: %s", 
 
				timestr, me, who, umsg))
 
	} else
 
		print_message(("[%s]%s: %s", me, who, umsg))
 

	
 
	if(utf8)
 
		FREE(umsg);
 
}
 

	
 
static void ext_yahoo_rejected(int id, const char *who, const char *msg)
 
{
 
	print_message(("%s has rejected you%s%s", who, 
 
				(msg?" with the message:\n":"."), 
 
				(msg?msg:"")));
 
}
 

	
 
static void ext_yahoo_contact_added(int id, const char *myid, const char *who, const char *msg)
 
{
 
	char buff[1024];
 

	
 
	snprintf(buff, sizeof(buff), "%s, the yahoo user %s has added you to their contact list", myid, who);
 
	if(msg) {
 
		strcat(buff, " with the following message:\n");
 
		strcat(buff, msg);
 
		strcat(buff, "\n");
 
	} else {
 
		strcat(buff, ".  ");
 
	}
 
	strcat(buff, "Do you want to allow this [Y/N]?");
 

	
 
/*	print_message((buff));
 
	scanf("%c", &choice);
 
	if(choice != 'y' && choice != 'Y')
 
		yahoo_reject_buddy(id, who, "Thanks, but no thanks.");
 
*/
 
}
 

	
 
static void ext_yahoo_typing_notify(int id, const char* me, const char *who, int stat)
 
{
 
	if(stat && do_typing_notify)
 
		print_message(("[%s]%s is typing...", me, who));
 
}
 

	
 
static void ext_yahoo_game_notify(int id, const char *me, const char *who, int stat, const char *msg)
 
{
 
}
 

	
 
static void ext_yahoo_mail_notify(int id, const char *from, const char *subj, int cnt)
 
{
 
	char buff[1024] = {0};
 
	
 
	if(!do_mail_notify)
 
		return;
 

	
 
	if(from && subj)
 
		snprintf(buff, sizeof(buff), 
 
				"You have new mail from %s about %s\n", 
 
				from, subj);
 
	if(cnt) {
 
		char buff2[100];
 
		snprintf(buff2, sizeof(buff2), 
 
				"You have %d message%s\n", 
 
				cnt, cnt==1?"":"s");
 
		strcat(buff, buff2);
 
	}
 

	
 
	if(buff[0])
 
		print_message((buff));
 
}
 

	
 
static void ext_yahoo_got_webcam_image(int id, const char *who,
 
		const unsigned char *image, unsigned int image_size, unsigned int real_size,
 
		unsigned int timestamp)
 
{
 
	static unsigned char *cur_image = NULL;
 
	static unsigned int cur_image_len = 0;
 
	static unsigned int image_num = 0;
 
	FILE* f_image;
 
	char fname[1024];
 

	
 
	/* copy image part to cur_image */
 
	if (real_size)
 
	{
 
		if (!cur_image) cur_image = y_new0(unsigned char, image_size);
 
		memcpy(cur_image + cur_image_len, image, real_size);
 
		cur_image_len += real_size;
 
	}
 

	
 
	if (image_size == cur_image_len)
 
	{
 
		print_message(("Received a image update at %d (%d bytes)",
 
			 timestamp, image_size));
 

	
 
		/* if we recieved an image then write it to file */
 
		if (image_size)
 
		{
 
			sprintf(fname, "images/%s_%.3d.jpc", who, image_num++);
 

	
 
			if ((f_image = fopen(fname, "w")) != NULL) {
 
				fwrite(cur_image, image_size, 1, f_image);
 
				fclose(f_image);
 
			} else {
 
				printf("Error writing to %s\n", fname);
 
			}
 
			FREE(cur_image);
 
			cur_image_len = 0;
 
			if (image_num > 999) image_num = 0;
 
		}
 
	}
 
}
 

	
 
static void ext_yahoo_webcam_viewer(int id, const char *who, int connect)
 
{
 
	switch (connect)
 
	{
 
		case 0:
 
			print_message(("%s has stopped viewing your webcam", who));
 
			break;
 
		case 1:
 
			print_message(("%s has started viewing your webcam", who));
 
			break;
 
		case 2:
 
			print_message(("%s is trying to view your webcam", who));
 
			yahoo_webcam_accept_viewer(id, who, accept_webcam_viewers);
 
			break;
 
	}
 
}
 

	
 
static void ext_yahoo_webcam_closed(int id, const char *who, int reason)
 
{
 
	switch(reason)
 
	{
 
		case 1:
 
			print_message(("%s stopped broadcasting", who));
 
			break;
 
		case 2:
 
			print_message(("%s cancelled viewing permission", who));
 
			break;
 
		case 3:
 
			print_message(("%s declines permission to view his/her webcam", who));
 
			break;
 
		case 4:
 
			print_message(("%s does not have his/her webcam online", who));
 
			break;
 
	}
 
}
 

	
 
static void ext_yahoo_webcam_data_request(int id, int send)
 
{
 
	webcam_id = id;
 

	
 
	if (send) {
 
		print_message(("Got request to start sending images"));
 
		if (!webcamTimer)
 
			rearm(&webcamTimer, 2);
 
	} else {
 
		print_message(("Got request to stop sending images"));
 
	}
 
	send_webcam_images = send;
 
}
 

	
 
static void ext_yahoo_webcam_invite(int id, const char *me, const char *from)
 
{
 
	print_message(("Got a webcam invitation to %s from %s", me, from));
 
}
 

	
 
static void ext_yahoo_webcam_invite_reply(int id, const char *me, const char *from, int accept)
 
{
 
	if(accept) {
 
		print_message(("[%s]%s accepted webcam invitation...", me, from));
 
	} else {
 
		print_message(("[%s]%s declined webcam invitation...", me, from));
 
	}
 
}
 

	
 
static void ext_yahoo_system_message(int id, const char *me, const char *who, const char *msg)
 
{
 
	if(ignore_system)
 
		return;
 

	
 
	print_message(("Yahoo System Message: %s", msg));
 
}
 

	
 
void yahoo_logout()
 
{
 
	if (ylad->id <= 0) {
 
		return;
 
	}
 

	
 
	pingTimer=0;
 

	
 
	while(conferences) {
 
		YList * n = conferences->next;
 
		conf_room * cr = conferences->data;
 
		if(cr->joined)
 
			yahoo_conference_logoff(ylad->id, NULL, cr->members, cr->room_name);
 
		FREE(cr->me);
 
		FREE(cr->room_name);
 
		FREE(cr->host);
 
		while(cr->members) {
 
			YList *n = cr->members->next;
 
			FREE(cr->members->data);
 
			FREE(cr->members);
 
			cr->members=n;
 
		}
 
		FREE(cr);
 
		FREE(conferences);
 
		conferences = n;
 
	}
 
	
 
	yahoo_logoff(ylad->id);
 
	yahoo_close(ylad->id);
 

	
 
	ylad->status = YAHOO_STATUS_OFFLINE;
 
	ylad->id = 0;
 

	
 
	poll_loop=0;
 

	
 
	print_message(("logged_out"));
 
}
 

	
 
static void ext_yahoo_login(yahoo_local_account * ylad, int login_mode)
 
{
 
	LOG(("ext_yahoo_login"));
 

	
 
	ylad->id = yahoo_init_with_attributes(ylad->yahoo_id, ylad->password, 
 
			"local_host", local_host,
 
			"pager_port", 5050,
 
			NULL);
 
	ylad->status = YAHOO_STATUS_OFFLINE;
 
	yahoo_login(ylad->id, login_mode);
 

	
 
/*	if (ylad->id <= 0) {
 
		print_message(("Could not connect to Yahoo server.  Please verify that you are connected to the net and the pager host and port are correctly entered."));
 
		return;
 
	}
 
*/
 
	rearm(&pingTimer, 600);
 
}
 

	
 
static void ext_yahoo_got_cookies(int id)
 
{
 
	/*yahoo_get_yab(id);*/
 
}
 

	
 
static void ext_yahoo_login_response(int id, int succ, const char *url)
 
{
 
	char buff[1024];
 

	
 
	if(succ == YAHOO_LOGIN_OK) {
 
		ylad->status = yahoo_current_status(id);
 
		print_message(("logged in"));
 
		return;
 
		
 
	} else if(succ == YAHOO_LOGIN_UNAME) {
 

	
 
		snprintf(buff, sizeof(buff), "Could not log into Yahoo service - username not recognised.  Please verify that your username is correctly typed.");
 
	} else if(succ == YAHOO_LOGIN_PASSWD) {
 

	
 
		snprintf(buff, sizeof(buff), "Could not log into Yahoo service - password incorrect.  Please verify that your password is correctly typed.");
 

	
 
	} else if(succ == YAHOO_LOGIN_LOCK) {
 
		
 
		snprintf(buff, sizeof(buff), "Could not log into Yahoo service.  Your account has been locked.\nVisit %s to reactivate it.", url);
 

	
 
	} else if(succ == YAHOO_LOGIN_DUPL) {
 

	
 
		snprintf(buff, sizeof(buff), "You have been logged out of the yahoo service, possibly due to a duplicate login.");
 
	} else if(succ == YAHOO_LOGIN_SOCK) {
 

	
 
		snprintf(buff, sizeof(buff), "The server closed the socket.");
 
	} else {
 
		snprintf(buff, sizeof(buff), "Could not log in, unknown reason: %d.", succ);
 
	}
 

	
 
	ylad->status = YAHOO_STATUS_OFFLINE;
 
	print_message((buff));
 
	yahoo_logout();
 
	poll_loop=0;
 
}
 

	
 
static void ext_yahoo_error(int id, const char *err, int fatal, int num)
 
{
 
	fprintf(stdout, "Yahoo Error: ");
 
	fprintf(stdout, "%s", err);
 
	switch(num) {
 
		case E_UNKNOWN:
 
			fprintf(stdout, "unknown error %s", err);
 
			break;
 
		case E_CUSTOM:
 
			fprintf(stdout, "custom error %s", err);
 
			break;
 
		case E_CONFNOTAVAIL:
 
			fprintf(stdout, "%s is not available for the conference", err);
 
			break;
 
		case E_IGNOREDUP:
 
			fprintf(stdout, "%s is already ignored", err);
 
			break;
 
		case E_IGNORENONE:
 
			fprintf(stdout, "%s is not in the ignore list", err);
 
			break;
 
		case E_IGNORECONF:
 
			fprintf(stdout, "%s is in buddy list - cannot ignore ", err);
 
			break;
 
		case E_SYSTEM:
 
			fprintf(stdout, "system error %s", err);
 
			break;
 
		case E_CONNECTION:
 
			fprintf(stdout, "server connection error %s", err);
 
			break;
 
	}
 
	fprintf(stdout, "\n");
 
	if(fatal)
 
		yahoo_logout();
 
}
 

	
 
void yahoo_set_current_state(int yahoo_state)
 
{
 
	if (ylad->status == YAHOO_STATUS_OFFLINE && yahoo_state != YAHOO_STATUS_OFFLINE) {
 
		ext_yahoo_login(ylad, yahoo_state);
 
		return;
 
	} else if (ylad->status != YAHOO_STATUS_OFFLINE && yahoo_state == YAHOO_STATUS_OFFLINE) {
 
		yahoo_logout();
 
		return;
 
	}
 

	
 
	ylad->status = yahoo_state;
 
	if(yahoo_state == YAHOO_STATUS_CUSTOM) {
 
		if(ylad->msg)
 
			yahoo_set_away(ylad->id, yahoo_state, ylad->msg, 1);
 
		else
 
			yahoo_set_away(ylad->id, yahoo_state, "delta p * delta x too large", 1);
 
	} else
 
		yahoo_set_away(ylad->id, yahoo_state, NULL, 1);
 
}
 

	
 
static int ext_yahoo_connect(const char *host, int port)
 
{
 
	WARNING(("This should not be used anymore. File a bug report."));
 
	return -1;
 
}
 

	
 
/*************************************
 
 * Callback handling code starts here
 
 */
 
YList *connections = NULL;
 
struct _conn {
 
	int fd;
 
	SSL *ssl;
 
	int use_ssl;
 
	int remove;
 
};
 

	
 
struct conn_handler {
 
	struct _conn *con;
 
	int id;
 
	int tag;
 
	yahoo_input_condition cond;
 
	int remove;
 
	void *data;
 
};
 

	
 
static int connection_tags=0;
 

	
 
static int ext_yahoo_add_handler(int id, void *d, yahoo_input_condition cond, void *data)
 
{
 
	struct conn_handler *h = y_new0(struct conn_handler, 1);
 

	
 
	h->id = id;
 
	h->tag = ++connection_tags;
 
	h->con = d;
 
	h->cond = cond;
 
	h->data = data;
 

	
 
	LOG(("Add %d(%d) for %d, tag %d", h->con->fd, cond, id, h->tag));
 

	
 
	connections = y_list_prepend(connections, h);
 

	
 
	return h->tag;
 
}
 

	
 
static void ext_yahoo_remove_handler(int id, int tag)
 
{
 
	YList *l;
 
	if (!tag)
 
		return;
 

	
 
	for(l = connections; l; l = y_list_next(l)) {
 
		struct conn_handler *c = l->data;
 
		if(c->tag == tag) {
 
			/* don't actually remove it, just mark it for removal */
 
			/* we'll remove when we start the next poll cycle */
 
			LOG(("Marking id:%d fd:%p tag:%d for removal",
 
				c->id, c->con, c->tag));
 
			c->remove = 1;
 
			return;
 
		}
 
	}
 
}
 

	
 
static SSL *do_ssl_connect(int fd)
 
{
 
	SSL *ssl;
 
	SSL_CTX *ctx;
 

	
 
	LOG(("SSL Handshake"));
 

	
 
	SSL_library_init ();
 
	ctx = SSL_CTX_new(SSLv23_client_method());
 
	ssl = SSL_new(ctx);
 
	SSL_CTX_free(ctx);
 
	SSL_set_fd(ssl, fd);
 

	
 
	if (SSL_connect(ssl) == 1)
 
		return ssl;
 

	
 
	return NULL;
 
}
 

	
 
struct connect_callback_data {
 
	yahoo_connect_callback callback;
 
	void * callback_data;
 
	int id;
 
	int tag;
 
};
 

	
 
static void connect_complete(void *data, struct _conn *source, yahoo_input_condition condition)
 
{
 
	struct connect_callback_data *ccd = data;
 
	int error, err_size = sizeof(error);
 

	
 
	ext_yahoo_remove_handler(0, ccd->tag);
 
	getsockopt(source->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&err_size);
 

	
 
	if(error)
 
		goto err;
 

	
 
	LOG(("Connected fd: %d, error: %d", source->fd, error));
 

	
 
	if (source->use_ssl) {
 
		source->ssl = do_ssl_connect(source->fd);
 

	
 
		if (!source->ssl) {
 
err:
 
			LOG(("SSL Handshake Failed!"));
 
			ext_yahoo_close(source);
 

	
 
			ccd->callback(NULL, 0, ccd->callback_data);
 
			FREE(ccd);
 
			return;
 
		}
 
	}
 

	
 
	fcntl(source->fd, F_SETFL, O_NONBLOCK);
 

	
 
	ccd->callback(source, error, ccd->callback_data);
 
	FREE(ccd);
 
}
 

	
 
void yahoo_callback(struct conn_handler *c, yahoo_input_condition cond)
 
{
 
	int ret=1;
 
	char buff[1024]={0};
 

	
 
	if(c->id < 0) {
 
		connect_complete(c->data, c->con, cond);
 
	} else {
 
		if(cond & YAHOO_INPUT_READ)
 
			ret = yahoo_read_ready(c->id, c->con, c->data);
 
		if(ret>0 && cond & YAHOO_INPUT_WRITE)
 
			ret = yahoo_write_ready(c->id, c->con, c->data);
 

	
 
		if(ret == -1)
 
			snprintf(buff, sizeof(buff), 
 
				"Yahoo read error (%d): %s", errno, strerror(errno));
 
		else if(ret == 0)
 
			snprintf(buff, sizeof(buff), 
 
				"Yahoo read error: Server closed socket");
 

	
 
		if(buff[0])
 
			print_message((buff));
 
	}
 
}
 

	
 
static int ext_yahoo_write(void *fd, char *buf, int len)
 
{
 
	struct _conn *c = fd;
 

	
 
	if (c->use_ssl)
 
		return SSL_write(c->ssl, buf, len);
 
	else
 
		return write(c->fd, buf, len);
 
}
 

	
 
static int ext_yahoo_read(void *fd, char *buf, int len)
 
{
 
	struct _conn *c = fd;
 

	
 
	if (c->use_ssl)
 
		return SSL_read(c->ssl, buf, len);
 
	else
 
		return read(c->fd, buf, len);
 
}
 

	
 
static void ext_yahoo_close(void *fd)
 
{
 
	struct _conn *c = fd;
 
	YList *l;
 

	
 
	if (c->use_ssl)
 
		SSL_free(c->ssl);
 

	
 
	close(c->fd);
 
	c->fd = 0;
 

	
 
	/* Remove all handlers */
 
	for (l = connections; l; l = y_list_next(l)) {
 
		struct conn_handler *h = l->data;
 

	
 
		if (h->con == c)
 
			h->remove = 1;
 
	}
 

	
 
	c->remove = 1;
 
}
 

	
 
static int ext_yahoo_connect_async(int id, const char *host, int port, 
 
		yahoo_connect_callback callback, void *data, int use_ssl)
 
{
 
	struct sockaddr_in serv_addr;
 
	static struct hostent *server;
 
	int servfd;
 
	struct connect_callback_data * ccd;
 
	int error;
 
	SSL *ssl = NULL;
 

	
 
	struct _conn *c;
 

	
 
	LOG(("Connecting to %s:%d", host, port));
 
	
 
	if(!(server = gethostbyname(host))) {
 
		errno=h_errno;
 
		return -1;
 
	}
 

	
 
	if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 
		return -1;
 
	}
 

	
 
	memset(&serv_addr, 0, sizeof(serv_addr));
 
	serv_addr.sin_family = AF_INET;
 
	memcpy(&serv_addr.sin_addr.s_addr, *server->h_addr_list, server->h_length);
 
	serv_addr.sin_port = htons(port);
 

	
 
	c = y_new0(struct _conn, 1);
 
	c->fd = servfd;
 
	c->use_ssl = use_ssl;
 

	
 
	error = connect(servfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
 

	
 
	LOG(("Trying to connect: fd:%d error:%d", servfd, error));
 
	if(!error) {
 
		LOG(("Connected"));
 
		if (use_ssl) {
 
			ssl = do_ssl_connect(servfd);
 

	
 
			if (!ssl) {
 
				LOG(("SSL Handshake Failed!"));
 
				ext_yahoo_close(c);
 

	
 
				callback(NULL, 0, data);
 
				return -1;
 
			}
 
		}
 

	
 
		c->ssl = ssl;
 
		fcntl(c->fd, F_SETFL, O_NONBLOCK);
 

	
 
		callback(c, 0, data);
 
		return 0;
 
	} else if(error == -1 && errno == EINPROGRESS) {
 
		ccd = calloc(1, sizeof(struct connect_callback_data));
 
		ccd->callback = callback;
 
		ccd->callback_data = data;
 
		ccd->id = id;
 

	
 
		ccd->tag = ext_yahoo_add_handler(-1, c, YAHOO_INPUT_WRITE, ccd);
 
		return ccd->tag;
 
	} else {
 
		if(error == -1)
 
			LOG(("Connection failure: %s", strerror(errno)));
 

	
 
		ext_yahoo_close(c);
 

	
 
		callback(NULL, errno, data);
 
		return -1;
 
	}
 
}
 
/*
 
 * Callback handling code ends here
 
 ***********************************/
 

	
 
static void process_commands(char *line)
 
{
 
	char *cmd, *to, *msg;
 

	
 
	char *tmp, *start;
 
	char *copy = strdup(line);
 
	int yid = 0;
 

	
 
	enum yahoo_status state;
 

	
 
	start = cmd = copy;
 
	tmp = strchr(copy, ' ');
 
	if(tmp) {
 
		*tmp = '\0';
 
		copy = tmp+1;
 
	} else {
 
		copy = NULL;
 
	}
 

	
 
	if(!strncasecmp(cmd, "MSG", strlen("MSG"))) {
 
		/* send a message */
 
		to = copy;
 
		tmp = strchr(copy, ' ');
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
		}
 
		msg = copy;
 
		if(to && msg) {
 
			if(!strcmp(msg, "\a"))
 
				yahoo_send_im(ylad->id, NULL, to, "<ding>", 0,0);
 
			else {
 
				msg = y_str_to_utf8(msg);
 
				yahoo_send_im(ylad->id, NULL, to, msg, 1,0);
 
				FREE(msg)
 
			}
 
		}
 
	} else if(!strncasecmp(cmd, "CMS", strlen("CMS"))) {
 
		/* send a message */
 
		conf_room * cr;
 
		to = copy;
 
		tmp = strchr(copy, ' ');
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
		}
 
		msg = copy;
 
		cr = find_conf_room_by_name_and_id(ylad->id, NULL, to);
 
		if(!cr) {
 
			print_message(("no such room: %s", copy));
 
			goto end_parse;
 
		}
 
		if(msg)
 
			yahoo_conference_message(ylad->id, NULL, cr->members, to, msg, 0);
 
	} else if(!strncasecmp(cmd, "CLS", strlen("CLS"))) {
 
		YList * l;
 
		if(copy) {
 
			conf_room * cr = find_conf_room_by_name_and_id(ylad->id, NULL, copy);
 
			if(!cr) {
 
				print_message(("no such room: %s", copy));
 
				goto end_parse;
 
			}
 
			print_message(("Room: %s", copy));
 
			for(l = cr->members; l; l=l->next) {
 
				print_message(("%s", (char *)l->data))
 
			}
 
		} else {
 
			print_message(("All Rooms:"));
 
			for(l = conferences; l; l=l->next) {
 
				conf_room * cr = l->data;
 
				print_message(("%s", cr->room_name));
 
			}
 
		}
 

	
 
	} else if(!strncasecmp(cmd, "CCR", strlen("CCR"))) {
 
		conf_room * cr = y_new0(conf_room, 1);
 
		while((tmp = strchr(copy, ' ')) != NULL) {
 
			*tmp = '\0';
 
			if(!cr->room_name)
 
				cr->room_name = strdup(copy);
 
			else
 
				cr->members = y_list_append(cr->members,
 
						strdup(copy));
 
			copy = tmp+1;
 
		}
 
		cr->members = y_list_append(cr->members, strdup(copy));
 

	
 
		if(!cr->room_name || !cr->members) {
 
			FREE(cr);
 
		} else {
 
			cr->id = ylad->id;
 
			cr->joined = 1;
 
			conferences = y_list_append(conferences, cr);
 
			yahoo_conference_invite(ylad->id, NULL, cr->members, cr->room_name, "Join my conference");
 
			cr->members = y_list_append(cr->members,strdup(ylad->yahoo_id));
 
		}
 
	} else if(!strncasecmp(cmd, "CIN", strlen("CIN"))) {
 
		conf_room * cr;
 
		char * room=copy;
 
		YList * l1, *l = NULL;
 

	
 
		while((tmp = strchr(copy, ' ')) != NULL) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
			l = y_list_append(l, copy);
 
		}
 

	
 
		cr = find_conf_room_by_name_and_id(ylad->id, NULL, room);
 
		if(!cr) {
 
			print_message(("no such room: %s", room));
 
			y_list_free(l);
 
			goto end_parse;
 
		}
 

	
 
		for(l1 = l; l1; l1=l1->next) {
 
			char * w = l1->data;
 
			yahoo_conference_addinvite(ylad->id, NULL, w, room, cr->members, "Join my conference");
 
			cr->members = y_list_append(cr->members, strdup(w));
 
		}
 
		y_list_free(l);
 

	
 
	} else if(!strncasecmp(cmd, "CLN", strlen("CLN"))) {
 
		conf_room * cr = find_conf_room_by_name_and_id(ylad->id, NULL, copy);
 
		YList * l;
 
		if(!cr) {
 
			print_message(("no such room: %s", copy));
 
			goto end_parse;
 
		}
 

	
 
		cr->joined = 1;
 
		for(l = cr->members; l; l=l->next) {
 
			char * w = l->data;
 
			if(!strcmp(w, ylad->yahoo_id))
 
				break;
 
		}
 
		if(!l)
 
			cr->members = y_list_append(cr->members, strdup(ylad->yahoo_id));
 
		yahoo_conference_logon(ylad->id, NULL, cr->members, copy);
 

	
 
	} else if(!strncasecmp(cmd, "CLF", strlen("CLF"))) {
 
		conf_room * cr = find_conf_room_by_name_and_id(ylad->id, NULL, copy);
 
		
 
		if(!cr) {
 
			print_message(("no such room: %s", copy));
 
			goto end_parse;
 
		}
 

	
 
		yahoo_conference_logoff(ylad->id, NULL, cr->members, copy);
 

	
 
		conferences = y_list_remove(conferences, cr);
 
		FREE(cr->room_name);
 
		FREE(cr->host);
 
		while(cr->members) {
 
			YList *n = cr->members->next;
 
			FREE(cr->members->data);
 
			FREE(cr->members);
 
			cr->members=n;
 
		}
 
		FREE(cr);
 

	
 
	} else if(!strncasecmp(cmd, "CDC", strlen("CDC"))) {
 
		conf_room * cr;
 
		char * room = copy;
 
		tmp = strchr(copy, ' ');
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
			msg = copy;
 
		} else {
 
			msg = "Thanks, but no thanks!";
 
		}
 
		
 
		cr = find_conf_room_by_name_and_id(ylad->id, NULL, room);
 
		if(!cr) {
 
			print_message(("no such room: %s", room));
 
			goto end_parse;
 
		}
 

	
 
		yahoo_conference_decline(ylad->id, NULL, cr->members, room,msg);
 

	
 
		conferences = y_list_remove(conferences, cr);
 
		FREE(cr->room_name);
 
		FREE(cr->host);
 
		while(cr->members) {
 
			YList *n = cr->members->next;
 
			FREE(cr->members->data);
 
			FREE(cr->members);
 
			cr->members=n;
 
		}
 
		FREE(cr);
 

	
 

	
 
	} else if(!strncasecmp(cmd, "CHL", strlen("CHL"))) {
 
		int roomid;
 
		roomid = atoi(copy);
 
		yahoo_get_chatrooms(ylad->id, roomid);
 
	} else if(!strncasecmp(cmd, "CHJ", strlen("CHJ"))) {
 
		char *roomid, *roomname;
 
/* Linux, FreeBSD, Solaris:1 */
 
/* 1600326591 */
 
		roomid = copy;
 
		tmp = strchr(copy, ' ');
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
		}
 
		roomname = copy;
 
		if(roomid && roomname) {
 
			yahoo_chat_logon(ylad->id, NULL, roomname, roomid);
 
		}
 

	
 
	} else if(!strncasecmp(cmd, "CHM", strlen("CHM"))) {
 
		char *msg, *roomname;
 
		roomname = copy;
 
		tmp = strstr(copy, "  ");
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+2;
 
		}
 
		msg = copy;
 
		if(roomname && msg) {
 
			yahoo_chat_message(ylad->id, NULL, roomname, msg, 1, 0);
 
		}
 

	
 
	} else if(!strncasecmp(cmd, "CHX", strlen("CHX"))) {
 
		yahoo_chat_logoff(ylad->id, NULL);
 
	} else if(!strncasecmp(cmd, "STA", strlen("STA"))) {
 
		if(isdigit(copy[0])) {
 
			state = (enum yahoo_status)atoi(copy);
 
			copy = strchr(copy, ' ');
 
			if(state == 99) {
 
				if(copy)
 
					msg = copy;
 
				else
 
					msg = "delta x * delta p too large";
 
			} else
 
				msg = NULL;
 
		} else {
 
			state = YAHOO_STATUS_CUSTOM;
 
			msg = copy;
 
		}
 

	
 
		yahoo_set_away(ylad->id, state, msg, 1);
 

	
 
	} else if(!strncasecmp(cmd, "OFF", strlen("OFF"))) {
 
		/* go offline */
 
		printf("Going offline\n");
 
		poll_loop=0;
 
	} else if(!strncasecmp(cmd, "IDS", strlen("IDS"))) {
 
		/* print identities */
 
		const YList * ids = yahoo_get_identities(ylad->id);
 
		printf("Identities: ");
 
		for(; ids; ids = ids->next)
 
			printf("%s, ", (char *)ids->data);
 
		printf("\n");
 
	} else if(!strncasecmp(cmd, "AID", strlen("AID"))) {
 
		/* activate identity */
 
		yahoo_set_identity_status(ylad->id, copy, 1);
 
	} else if(!strncasecmp(cmd, "DID", strlen("DID"))) {
 
		/* deactivate identity */
 
		yahoo_set_identity_status(ylad->id, copy, 0);
 
	} else if(!strncasecmp(cmd, "LST", strlen("LST"))) {
 
		YList * b = buddies;
 
		for(; b; b=b->next) {
 
			yahoo_account * ya = b->data;
 
			if(ya->status == YAHOO_STATUS_OFFLINE)
 
				continue;
 
			if(ya->msg)
 
				print_message(("%s (%s) is now %s", ya->name, ya->yahoo_id, 
 
							ya->msg))
 
			else
 
				print_message(("%s (%s) is now %s", ya->name, ya->yahoo_id, 
 
						yahoo_status_code(ya->status)))
 
		}
 
	} else if(!strncasecmp(cmd, "NAM", strlen("NAM"))) {
 
		struct yab * yab;
 
		
 
		to = copy;
 
		tmp = strchr(copy, ' ');
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
		}
 
		yid = atoi(copy);
 

	
 
		tmp = strchr(copy, ' ');
 
		if(tmp) {
 
			*tmp = '\0';
 
			copy = tmp+1;
 
		}
 
		msg = copy;
 

	
 
		if(to && msg) {
 
			yab = y_new0(struct yab, 1);
 
			yab->id = to;
 
			yab->yid = yid;	/* Only do this if you have got it from the server */
 
			yab->nname = msg;
 
			yahoo_set_yab(ylad->id, yab);
 
			FREE(yab);
 
		}
 
	} else if(!strncasecmp(cmd, "WCAM", strlen("WCAM"))) {
 
		if (copy)
 
		{
 
			printf("Viewing webcam (%s)\n", copy);
 
			webcam_direction = YAHOO_WEBCAM_DOWNLOAD;
 
			yahoo_webcam_get_feed(ylad->id, copy);
 
		} else {
 
			printf("Starting webcam\n");
 
			webcam_direction = YAHOO_WEBCAM_UPLOAD;
 
			yahoo_webcam_get_feed(ylad->id, NULL);
 
		}
 
	} else if(!strncasecmp(cmd, "WINV", strlen("WINV"))) {
 
		printf("Inviting %s to view webcam\n", copy);
 
		yahoo_webcam_invite(ylad->id, copy);
 
	} else {
 
		fprintf(stderr, "Unknown command: %s\n", cmd);
 
	}
 

	
 
end_parse:
 
	FREE(start);
 
}
 

	
 
#ifndef _WIN32
 
static void local_input_callback(int source)
 
{
 
	char line[1024] = {0};
 
	int i;
 
	char c;
 
	i=0; c=0;
 
	do {
 
		if(read(source, &c, 1) <= 0)
 
			c='\0';
 
		if(c == '\r')
 
			continue;
 
		if(c == '\n')
 
			break;
 
		if(c == '\b') {
 
			if(!i)
 
				continue;
 
			c = '\0';
 
			i--;
 
		}
 
		if(c) {
 
			line[i++] = c;
 
			line[i]='\0';
 
		}
 
	} while(i<1023 && c != '\n');
 

	
 
	if(line[0])
 
		process_commands(line);
 
}
 
#else
 
#include <conio.h>
 
static void local_input_callback(char c)
 
{
 
	static char line[1024] = {0};
 
	static int line_length = 0;
 

	
 
	if (c == '\b' || (int)c == 127) {
 
		if (line_length > 0) {
 
			_cputs("\b \b");
 
			line_length--;
 
		}
 
		return;
 
	}
 

	
 
	if (c == '\n' || c == '\r' || c == 3) {
 
		_cputs("\n");
 
		line[line_length] = 0;
 
		process_commands(line);
 
		line_length = 0;
 
		line[0] = 0;
 
		return;
 
	}
 

	
 
	_putch(c);
 
	line[line_length++] = c;
 
}
 
#endif
 

	
 
int main(int argc, char * argv[])
 
{
 
	int status;
 
	int log_level;
 
	int lfd=0;
 

	
 
	fd_set inp, outp;
 
	struct timeval tv;
 

	
 
#ifndef _WIN32
 
	int fd_stdin = fileno(stdin);
 
#endif
 
	YList *l=connections;
 

	
 
#ifdef _WIN32
 
	WSADATA wsa;	
 
	if (WSAStartup(MAKEWORD(2,2), &wsa))
 
		return -1;
 
#endif
 

	
 
	ylad = y_new0(yahoo_local_account, 1);
 

	
 
	local_host = strdup(get_local_addresses());
 

	
 
	printf("Yahoo Id: ");
 
	scanf("%s", ylad->yahoo_id);
 
	printf("Password: ");
 
#ifdef _WIN32
 
	scanf("%s", ylad->password);
 
#else
 
	{
 
		tcflag_t oflags;
 
		struct termios term;
 
		tcgetattr(fd_stdin, &term);
 
		oflags = term.c_lflag;
 
		term.c_lflag = oflags & ~(ECHO | ECHOK | ICANON);
 
		term.c_cc[VTIME] = 1;
 
		tcsetattr(fd_stdin, TCSANOW, &term);
 
		
 
		scanf("%s", ylad->password);
 

	
 
		term.c_lflag = oflags;
 
		term.c_cc[VTIME] = 0;
 
		tcsetattr(fd_stdin, TCSANOW, &term);
 
	}
 
	printf("\n");
 
#endif
 

	
 
	printf("Initial Status: ");
 
	scanf("%d", &status);
 

	
 
	printf("Log Level: ");
 
	scanf("%d", &log_level);
 
	do_yahoo_debug=log_level;
 

	
 
	register_callbacks();
 
	yahoo_set_log_level(log_level);
 

	
 
	ext_yahoo_login(ylad, status);
 

	
 
	while(poll_loop) {
 
		FD_ZERO(&inp);
 
		FD_ZERO(&outp);
 
#ifndef _WIN32
 
		FD_SET(fd_stdin, &inp);
 
		tv.tv_sec=1;
 
		tv.tv_usec=0;
 
#else
 
		tv.tv_sec=0;
 
		tv.tv_usec=1E4;
 
#endif
 
		lfd=0;
 

	
 
		for(l=connections; l; ) {
 
			struct conn_handler *c = l->data;
 
			if(c->remove) {
 
				YList *n = y_list_next(l);
 
				LOG(("Removing id:%d fd:%d", c->id, c->con->fd));
 
				connections = y_list_remove_link(connections, l);
 
				y_list_free_1(l);
 
				FREE(c);
 
				l=n;
 
			} else {
 
				if(c->cond & YAHOO_INPUT_READ)
 
					FD_SET(c->con->fd, &inp);
 
				if(c->cond & YAHOO_INPUT_WRITE)
 
					FD_SET(c->con->fd, &outp);
 
				if(lfd < c->con->fd)
 
					lfd = c->con->fd;
 
				l = y_list_next(l);
 
			}
 
		}
 

	
 
		select(lfd + 1, &inp, &outp, NULL, &tv);
 
		time(&curTime);
 

	
 
#ifndef _WIN32
 
		if(FD_ISSET(fd_stdin, &inp))	local_input_callback(0);
 
#else
 
		if (_kbhit()) local_input_callback(_getch());
 
#endif
 

	
 
		for(l = connections; l; l = y_list_next(l)) {
 
			struct conn_handler *c = l->data;
 
			if(c->con->remove) {
 
				FREE(c->con);
 
				c->con = NULL;
 
				continue;
 
			}
 
			if(c->remove)
 
				continue;
 
			if(FD_ISSET(c->con->fd, &inp))
 
				yahoo_callback(c, YAHOO_INPUT_READ);
 
			if(FD_ISSET(c->con->fd, &outp))
 
				yahoo_callback(c, YAHOO_INPUT_WRITE);
 
		}
 

	
 
		if(expired(pingTimer))		yahoo_ping_timeout_callback();
 
		if(expired(webcamTimer))	yahoo_webcam_timeout_callback(webcam_id);
 
	}
 
	LOG(("Exited loop"));
 

	
 
	while(connections) {
 
		YList *tmp = connections;
 
		struct conn_handler *c = connections->data;
 
		FREE(c);
 
		connections = y_list_remove_link(connections, connections);
 
		y_list_free_1(tmp);
 
	}
 

	
 
	yahoo_logout();
 

	
 
	FREE(ylad);
 

	
 
#ifdef _WIN32
 
	WSACleanup();
 
#endif
 
	return 0;
 
}
 

	
 
static void ext_yahoo_got_file(int id, const char *me, const char *who, const char *msg, const char *fname, 
 
	unsigned long fesize, char *trid)
 
{
 
	LOG(("Got a File transfer request (%s, %ld bytes) from %s", fname, fesize, who));
 
}
 

	
 
static void ext_yahoo_file_transfer_done(int id, int response, void *data)
 
{
 
}
 

	
 
static char *ext_yahoo_get_ip_addr(const char *domain)
 
{
 
	return NULL;
 
}
 

	
 
static void ext_yahoo_got_ft_data(int id, const unsigned char *in, int count, void *data)
 
{
 
}
 

	
 
static void ext_yahoo_got_identities(int id, YList * ids)
 
{
 
}
 

	
 
static void ext_yahoo_chat_yahoologout(int id, const char *me)
 
{ 
 
 	LOG(("got chat logout for %s", me));
 
}
 

	
 
static void ext_yahoo_chat_yahooerror(int id, const char *me)
 
{ 
 
 	LOG(("got chat error for %s", me));
 
}
 

	
 
static void ext_yahoo_got_ping(int id, const char *errormsg)
 
{ 
 
 	LOG(("got ping errormsg %s", errormsg));
 
}
 

	
 
static void ext_yahoo_got_search_result(int id, int found, int start, int total, YList *contacts)
 
{
 
	LOG(("got search result"));
 
}
 

	
 
static void ext_yahoo_got_buddyicon_checksum(int id, const char *a, const char *b, int checksum)
 
{
 
	LOG(("got buddy icon checksum"));
 
}
 

	
 
static void ext_yahoo_got_buddy_change_group(int id, const char *me, const char *who, 
 
	const char *old_group, const char *new_group)
 
{
 
}
 

	
 
static void ext_yahoo_got_buddyicon(int id, const char *a, const char *b, const char *c, int checksum)
 
{
 
	LOG(("got buddy icon"));
 
}
 

	
 
static void ext_yahoo_buddyicon_uploaded(int id, const char *url)
 
{
 
	LOG(("buddy icon uploaded"));
 
}
 

	
 
static void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who)
 
{
 
	LOG(("got buddy icon request from %s",who));
 
}
 

	
 
static void register_callbacks()
 
{
 
	static struct yahoo_callbacks yc;
 

	
 
	yc.ext_yahoo_login_response = ext_yahoo_login_response;
 
	yc.ext_yahoo_got_buddies = ext_yahoo_got_buddies;
 
	yc.ext_yahoo_got_ignore = ext_yahoo_got_ignore;
 
	yc.ext_yahoo_got_identities = ext_yahoo_got_identities;
 
	yc.ext_yahoo_got_cookies = ext_yahoo_got_cookies;
 
	yc.ext_yahoo_status_changed = ext_yahoo_status_changed;
 
	yc.ext_yahoo_got_im = ext_yahoo_got_im;
 
	yc.ext_yahoo_got_buzz = ext_yahoo_got_buzz;
 
	yc.ext_yahoo_got_conf_invite = ext_yahoo_got_conf_invite;
 
	yc.ext_yahoo_conf_userdecline = ext_yahoo_conf_userdecline;
 
	yc.ext_yahoo_conf_userjoin = ext_yahoo_conf_userjoin;
 
	yc.ext_yahoo_conf_userleave = ext_yahoo_conf_userleave;
 
	yc.ext_yahoo_conf_message = ext_yahoo_conf_message;
 
	yc.ext_yahoo_chat_cat_xml = ext_yahoo_chat_cat_xml;
 
	yc.ext_yahoo_chat_join = ext_yahoo_chat_join;
 
	yc.ext_yahoo_chat_userjoin = ext_yahoo_chat_userjoin;
 
	yc.ext_yahoo_chat_userleave = ext_yahoo_chat_userleave;
 
	yc.ext_yahoo_chat_message = ext_yahoo_chat_message;
 
	yc.ext_yahoo_chat_yahoologout = ext_yahoo_chat_yahoologout;
 
	yc.ext_yahoo_chat_yahooerror = ext_yahoo_chat_yahooerror;
 
	yc.ext_yahoo_got_webcam_image = ext_yahoo_got_webcam_image;
 
	yc.ext_yahoo_webcam_invite = ext_yahoo_webcam_invite;
 
	yc.ext_yahoo_webcam_invite_reply = ext_yahoo_webcam_invite_reply;
 
	yc.ext_yahoo_webcam_closed = ext_yahoo_webcam_closed;
 
	yc.ext_yahoo_webcam_viewer = ext_yahoo_webcam_viewer;
 
	yc.ext_yahoo_webcam_data_request = ext_yahoo_webcam_data_request;
 
	yc.ext_yahoo_got_file = ext_yahoo_got_file;
 
	yc.ext_yahoo_got_ft_data = ext_yahoo_got_ft_data;
 
	yc.ext_yahoo_get_ip_addr = ext_yahoo_get_ip_addr;
 
	yc.ext_yahoo_file_transfer_done = ext_yahoo_file_transfer_done;
 
	yc.ext_yahoo_contact_added = ext_yahoo_contact_added;
 
	yc.ext_yahoo_rejected = ext_yahoo_rejected;
 
	yc.ext_yahoo_typing_notify = ext_yahoo_typing_notify;
 
	yc.ext_yahoo_game_notify = ext_yahoo_game_notify;
 
	yc.ext_yahoo_mail_notify = ext_yahoo_mail_notify;
 
	yc.ext_yahoo_got_search_result = ext_yahoo_got_search_result;
 
	yc.ext_yahoo_system_message = ext_yahoo_system_message;
 
	yc.ext_yahoo_error = ext_yahoo_error;
 
	yc.ext_yahoo_log = ext_yahoo_log;
 
	yc.ext_yahoo_add_handler = ext_yahoo_add_handler;
 
	yc.ext_yahoo_remove_handler = ext_yahoo_remove_handler;
 
	yc.ext_yahoo_connect = ext_yahoo_connect;
 
	yc.ext_yahoo_connect_async = ext_yahoo_connect_async;
 
	yc.ext_yahoo_read = ext_yahoo_read;
 
	yc.ext_yahoo_write = ext_yahoo_write;
 
	yc.ext_yahoo_close = ext_yahoo_close;
 
	yc.ext_yahoo_got_buddyicon = ext_yahoo_got_buddyicon;
 
	yc.ext_yahoo_got_buddyicon_checksum = ext_yahoo_got_buddyicon_checksum;
 
	yc.ext_yahoo_buddyicon_uploaded = ext_yahoo_buddyicon_uploaded;
 
	yc.ext_yahoo_got_buddyicon_request = ext_yahoo_got_buddyicon_request;
 
	yc.ext_yahoo_got_ping = ext_yahoo_got_ping;
 
	yc.ext_yahoo_got_buddy_change_group = ext_yahoo_got_buddy_change_group;
 

	
 
	yahoo_register_callbacks(&yc);
 
}
 

	
backends/libyahoo2/yahoo/crypt.c
Show inline comments
 
new file 100644
 
/* One way encryption based on MD5 sum.
 
   Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
 
   This file is part of the GNU C Library.
 
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 

	
 
   The GNU C Library is free software; you can redistribute it and/or
 
   modify it under the terms of the GNU Lesser General Public
 
   License as published by the Free Software Foundation; either
 
   version 2.1 of the License, or (at your option) any later version.
 

	
 
   The GNU C Library 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
 
   Lesser General Public License for more details.
 

	
 
   You should have received a copy of the GNU Lesser General Public
 
   License along with the GNU C Library; if not, write to the Free
 
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
   02111-1307 USA.  */
 

	
 
/* warmenhoven took this file and made it work with the md5.[ch] we
 
 * already had. isn't that lovely. people should just use linux or
 
 * freebsd, crypt works properly on those systems. i hate solaris */
 

	
 
#if HAVE_CONFIG_H
 
#  include <config.h>
 
#endif
 

	
 
#if HAVE_STRING_H
 
#  include <string.h>
 
#elif HAVE_STRINGS_H
 
#  include <strings.h>
 
#endif
 

	
 
#include <stdlib.h>
 
#include "yahoo_util.h"
 

	
 
#include "md5.h"
 

	
 
/* Define our magic string to mark salt for MD5 "encryption"
 
   replacement.  This is meant to be the same as for other MD5 based
 
   encryption implementations.  */
 
static const char md5_salt_prefix[] = "$1$";
 

	
 
/* Table with characters for base64 transformation.  */
 
static const char b64t[64] =
 
	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 

	
 
char *yahoo_crypt(char *key, char *salt)
 
{
 
	char *buffer = NULL;
 
	int buflen = 0;
 
	int needed = 3 + strlen(salt) + 1 + 26 + 1;
 

	
 
	md5_byte_t alt_result[16];
 
	md5_state_t ctx;
 
	md5_state_t alt_ctx;
 
	size_t salt_len;
 
	size_t key_len;
 
	size_t cnt;
 
	char *cp;
 

	
 
	if (buflen < needed) {
 
		buflen = needed;
 
		if ((buffer = realloc(buffer, buflen)) == NULL)
 
			return NULL;
 
	}
 

	
 
	/* Find beginning of salt string.  The prefix should normally always
 
	   be present.  Just in case it is not.  */
 
	if (strncmp(md5_salt_prefix, salt, sizeof(md5_salt_prefix) - 1) == 0)
 
		/* Skip salt prefix.  */
 
		salt += sizeof(md5_salt_prefix) - 1;
 

	
 
	salt_len = MIN(strcspn(salt, "$"), 8);
 
	key_len = strlen(key);
 

	
 
	/* Prepare for the real work.  */
 
	md5_init(&ctx);
 

	
 
	/* Add the key string.  */
 
	md5_append(&ctx, (md5_byte_t *)key, key_len);
 

	
 
	/* Because the SALT argument need not always have the salt prefix we
 
	   add it separately.  */
 
	md5_append(&ctx, (md5_byte_t *)md5_salt_prefix,
 
		sizeof(md5_salt_prefix) - 1);
 

	
 
	/* The last part is the salt string.  This must be at most 8
 
	   characters and it ends at the first `$' character (for
 
	   compatibility which existing solutions).  */
 
	md5_append(&ctx, (md5_byte_t *)salt, salt_len);
 

	
 
	/* Compute alternate MD5 sum with input KEY, SALT, and KEY.  The
 
	   final result will be added to the first context.  */
 
	md5_init(&alt_ctx);
 

	
 
	/* Add key.  */
 
	md5_append(&alt_ctx, (md5_byte_t *)key, key_len);
 

	
 
	/* Add salt.  */
 
	md5_append(&alt_ctx, (md5_byte_t *)salt, salt_len);
 

	
 
	/* Add key again.  */
 
	md5_append(&alt_ctx, (md5_byte_t *)key, key_len);
 

	
 
	/* Now get result of this (16 bytes) and add it to the other
 
	   context.  */
 
	md5_finish(&alt_ctx, alt_result);
 

	
 
	/* Add for any character in the key one byte of the alternate sum.  */
 
	for (cnt = key_len; cnt > 16; cnt -= 16)
 
		md5_append(&ctx, alt_result, 16);
 
	md5_append(&ctx, alt_result, cnt);
 

	
 
	/* For the following code we need a NUL byte.  */
 
	alt_result[0] = '\0';
 

	
 
	/* The original implementation now does something weird: for every 1
 
	   bit in the key the first 0 is added to the buffer, for every 0
 
	   bit the first character of the key.  This does not seem to be
 
	   what was intended but we have to follow this to be compatible.  */
 
	for (cnt = key_len; cnt > 0; cnt >>= 1)
 
		md5_append(&ctx,
 
			(cnt & 1) != 0 ? alt_result : (md5_byte_t *)key, 1);
 

	
 
	/* Create intermediate result.  */
 
	md5_finish(&ctx, alt_result);
 

	
 
	/* Now comes another weirdness.  In fear of password crackers here
 
	   comes a quite long loop which just processes the output of the
 
	   previous round again.  We cannot ignore this here.  */
 
	for (cnt = 0; cnt < 1000; ++cnt) {
 
		/* New context.  */
 
		md5_init(&ctx);
 

	
 
		/* Add key or last result.  */
 
		if ((cnt & 1) != 0)
 
			md5_append(&ctx, (md5_byte_t *)key, key_len);
 
		else
 
			md5_append(&ctx, alt_result, 16);
 

	
 
		/* Add salt for numbers not divisible by 3.  */
 
		if (cnt % 3 != 0)
 
			md5_append(&ctx, (md5_byte_t *)salt, salt_len);
 

	
 
		/* Add key for numbers not divisible by 7.  */
 
		if (cnt % 7 != 0)
 
			md5_append(&ctx, (md5_byte_t *)key, key_len);
 

	
 
		/* Add key or last result.  */
 
		if ((cnt & 1) != 0)
 
			md5_append(&ctx, alt_result, 16);
 
		else
 
			md5_append(&ctx, (md5_byte_t *)key, key_len);
 

	
 
		/* Create intermediate result.  */
 
		md5_finish(&ctx, alt_result);
 
	}
 

	
 
	/* Now we can construct the result string.  It consists of three
 
	   parts.  */
 

	
 
	strncpy(buffer, md5_salt_prefix, MAX(0, buflen));
 
	cp = buffer + strlen(buffer);
 
	buflen -= sizeof(md5_salt_prefix);
 

	
 
	strncpy(cp, salt, MIN((size_t) buflen, salt_len));
 
	cp = cp + strlen(cp);
 
	buflen -= MIN((size_t) buflen, salt_len);
 

	
 
	if (buflen > 0) {
 
		*cp++ = '$';
 
		--buflen;
 
	}
 
#define b64_from_24bit(B2, B1, B0, N) \
 
	do { \
 
		unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
 
		int n = (N); \
 
		while (n-- > 0 && buflen > 0) { \
 
			*cp++ = b64t[w & 0x3f]; \
 
			--buflen; \
 
			w >>= 6; \
 
		}\
 
	} while (0)
 

	
 
	b64_from_24bit(alt_result[0], alt_result[6], alt_result[12], 4);
 
	b64_from_24bit(alt_result[1], alt_result[7], alt_result[13], 4);
 
	b64_from_24bit(alt_result[2], alt_result[8], alt_result[14], 4);
 
	b64_from_24bit(alt_result[3], alt_result[9], alt_result[15], 4);
 
	b64_from_24bit(alt_result[4], alt_result[10], alt_result[5], 4);
 
	b64_from_24bit(0, 0, alt_result[11], 2);
 
	if (buflen <= 0) {
 
		FREE(buffer);
 
	} else
 
		*cp = '\0';	/* Terminate the string.  */
 

	
 
	/* Clear the buffer for the intermediate result so that people
 
	   attaching to processes or reading core dumps cannot get any
 
	   information.  We do it in this way to clear correct_words[]
 
	   inside the MD5 implementation as well.  */
 
	md5_init(&ctx);
 
	md5_finish(&ctx, alt_result);
 
	memset(&ctx, '\0', sizeof(ctx));
 
	memset(&alt_ctx, '\0', sizeof(alt_ctx));
 

	
 
	return buffer;
 
}

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)