libwsw & wswutil release

This article introduces libwsw - C++ library for Jabber clients which provides XEP-136 support, AKA server-side message archiving, and wswutil - the tool for import / export operations on user history for XEP-136 compliant servers.



The goal of libwsw project is to develop cross-platform, easy to use and efficient library which can further be used by Jabber clients to support XEP-136 for server-side history archiving.

WSW stands for “Who Said What”

libwsw will provide high-level API to XEP-136 featues, i.e. retrieve collections / messages in the form convenient for Jabber clients, as well as for collections upload / removal, with the optional local caching support to speedup things and perform searches through the history.

Please note that currently the project is in its early stage, and is not ready for real use! I release it now mainly for usage with wswutil, see below. Of course, you can have a look at it for other purposes - for example, to help me with further development , but do not expect too much. Things that currently work OK are collections / messages direct retrieval and collections upload, both in synchronous and asynchronous mode. Cached mode is implemented, but it’s not yet debugged & tested well enough.

Documentation, as usual in such cases, does not exist yet, but the main files you need to be aware of are api.h and core.h, they are extensively commented, so it should be simple to understand how to use it. Also have a look at wswutil implementation for the example of library usage.

The library uses “drivers” concept to communicate with Jabber server - therefore it should be quite easy to add support for different XMPP libraries, including those that are embedded into clients implementations.

Currently gloox driver is provided, if I proceed with Psi integration - iris driver will also be added.

If you’d like to add support for new driver - have a look at drivers/xmpp/driver.h, it is also commented well enough to understand what should be done, plus, of course, have a look at gloox_drv.cpp for the example of implementation.

Downloading and building

libwsw downloads: sources of 1.0.0 version. The license is GPL. Compilation was tested on Win32/MSVC8 (with and without SOCI) and linux-amd64/g++-4.2 (currently only without SOCI). For compilation cmake is required.

Dependencies are:

  • boost - required, some header-only libs, date_time, optionally - threads for multi-threaded usage. Tested with 1.34.1 version.
  • gloox - currently required as so far it’s the only driver provided, in the future - optional. Tested with version.
  • SOCI - optional, for databases support. Tested with 2.2.0 version.

Future directions

My nearest plans are to debug / test cached mode and to introduce several other API calls to make library usage easier for clients, such as flat messages retrieval (so, just page through the set of messages without caring about collections at all) and different calculation routines, such as messages number estimation based on cache content.

After this is complete, I’d like to try to integrate the library into at least one Jabber client, most likely Psi, to check that API is indeed convenient for the tasks Jabber clients have and adjust / extend API, if needed.


Based on current libwsw implementation I’ve developed wswutil - this is a small tool which is able to import / export your history from / to XEP-136 compliant Jabber server (so far tested only with ejabberd + mod_archive_odbc). It uses XEP-136 format for message archiving as XML file with small extensions.

wswutil downloads: sources of 1.0.0 version, binaries of 1.0.0 version for Win32.

For Win32 binaries you’ll need run-time libraries from MS Visual C++ 2005 installed, can be downloaded here, though chances are you already have it.

The license is GPL. Compilation was tested on Win32/MSVC8 (with and without SOCI) and linux-amd64/g++-4.2 (currently only without SOCI). For compilation cmake is required.

The distribution also includes some (hacky) perl scripts to convert history exported from Miranda and Psi into XML format suitable for uploading.

Dependencies are:

  • libwsw - required (+ all its required dependencies, of course).
  • gloox - required, as it’s used directly to setup connection with server and communicate with it. Tested with version.
  • expat - required, for XEP-136 file format parsing. Tested with 2.0.0 version.

Please, feel free to post any issues you encounter with any of these as comments to this article!

Comment viewing options

ndl@home is currently in maintenance. During this maintenance it is not possible to change site content (like comments, pages and users).
Select your preferred way to display the comments and click "Save settings" to activate your changes.

Build problems

Can you possibly post some instructions on how to get this to build properly in Linux? I can get libwsw-1.0.0 to build fine though 'make install' doesn't do anything and neither does 'cmake -P cmake_install.cmake'.

To get wsutil to build, I tried to copy libwsw-1.0.0/src/wsw into wswutil-1.0.0/src. But I'm not sure what to do with liblibwsw.a. I tried placing it in wswutil-1.0.0, wswutil-1.0.0/src and even /usr/local/lib. Though whatever I do, I get these errors:

$ make
[ 50%] Building CXX object CMakeFiles/wswutil.dir/src/wswutil.o
Linking CXX executable wswutil
CMakeFiles/wswutil.dir/src/wswutil.o: In function `(anonymous namespace)::startElement(void*, char const*, char const**)':
wswutil.cpp:(.text+0x955): undefined reference to `WSW::DateTime::str2DateTime(std::basic_string, std::allocator > const&)'
wswutil.cpp:(.text+0x9e0): undefined reference to `WSW::Core::Message::setDirectionFromString(char const*)'
wswutil.cpp:(.text+0xa9e): undefined reference to `WSW::DateTime::str2DateTime(std::basic_string, std::allocator > const&)'
CMakeFiles/wswutil.dir/src/wswutil.o: In function `(anonymous namespace)::uploadCollection((anonymous namespace)::ParseInfo*)':
wswutil.cpp:(.text+0xb36): undefined reference to `WSW::API::updateCollectionSync(WSW::Core::Collection const&)'
CMakeFiles/wswutil.dir/src/wswutil.o: In function `WSWUtil::receiveMessage(WSW::Core::CollectionLink const&, std::pair const&)':
wswutil.cpp:(.text._ZN7WSWUtil14receiveMessageERKN3WSW4Core14CollectionLinkERKSt4pairIlNS1_7MessageEE[WSWUtil::receiveMessage(WSW::Core::CollectionLink const&, std::pair const&)]+0x119): undefined reference to `WSW::DateTime::dateTime2Str(boost::posix_time::ptime const&)'
CMakeFiles/wswutil.dir/src/wswutil.o: In function `WSWUtil::handleCollection(WSW::Core::CollectionInfo)':
wswutil.cpp:(.text._ZN7WSWUtil16handleCollectionEN3WSW4Core14CollectionInfoE[WSWUtil::handleCollection(WSW::Core::CollectionInfo)]+0x1c3): undefined reference to `WSW::DateTime::dateTime2Str(boost::posix_time::ptime const&)'
wswutil.cpp:(.text._ZN7WSWUtil16handleCollectionEN3WSW4Core14CollectionInfoE[WSWUtil::handleCollection(WSW::Core::CollectionInfo)]+0x4de): undefined reference to `WSW::Core::CollectionLink::isValid() const'
wswutil.cpp:(.text._ZN7WSWUtil16handleCollectionEN3WSW4Core14CollectionInfoE[WSWUtil::handleCollection(WSW::Core::CollectionInfo)]+0x4fb): undefined reference to `WSW::DateTime::dateTime2Str(boost::posix_time::ptime const&)'
wswutil.cpp:(.text._ZN7WSWUtil16handleCollectionEN3WSW4Core14CollectionInfoE[WSWUtil::handleCollection(WSW::Core::CollectionInfo)]+0x5c9): undefined reference to `WSW::Core::CollectionLink::isValid() const'
wswutil.cpp:(.text._ZN7WSWUtil16handleCollectionEN3WSW4Core14CollectionInfoE[WSWUtil::handleCollection(WSW::Core::CollectionInfo)]+0x5e6): undefined reference to `WSW::DateTime::dateTime2Str(boost::posix_time::ptime const&)'
wswutil.cpp:(.text._ZN7WSWUtil16handleCollectionEN3WSW4Core14CollectionInfoE[WSWUtil::handleCollection(WSW::Core::CollectionInfo)]+0x782): undefined reference to `WSW::API::getMessagesSync(WSW::Core::CollectionLink const&, long, long, boost::function const&), std::allocator > const&)'
CMakeFiles/wswutil.dir/src/wswutil.o: In function `WSWUtil::download()':
wswutil.cpp:(.text._ZN7WSWUtil8downloadEv[WSWUtil::download()]+0x623): undefined reference to `WSW::API::getCollectionsSync(std::basic_string, std::allocator > const&, long, long, boost::function const&), std::allocator > const&)'
CMakeFiles/wswutil.dir/src/wswutil.o: In function `WSW::Core::Collection::Collection()':
wswutil.cpp:(.text._ZN3WSW4Core10CollectionC1Ev[WSW::Core::Collection::Collection()]+0xd): undefined reference to `WSW::Core::CollectionInfo::CollectionInfo()'
CMakeFiles/wswutil.dir/src/wswutil.o: In function `WSWUtil::process()':
wswutil.cpp:(.text._ZN7WSWUtil7processEv[WSWUtil::process()]+0x831): undefined reference to `WSW::API::Options::Options()'
wswutil.cpp:(.text._ZN7WSWUtil7processEv[WSWUtil::process()]+0x85b): undefined reference to `WSW::Drivers::XMPP::GlooxDriver::GlooxDriver(gloox::Client*)'
wswutil.cpp:(.text._ZN7WSWUtil7processEv[WSWUtil::process()]+0x88c): undefined reference to `WSW::API::API(WSW::Drivers::XMPP::Driver*, WSW::API::Options const&)'
wswutil.cpp:(.text._ZN7WSWUtil7processEv[WSWUtil::process()]+0x98c): undefined reference to `WSW::API::~API()'
collect2: ld returned 1 exit status
make[2]: *** [wswutil] Error 1
make[1]: *** [CMakeFiles/wswutil.dir/all] Error 2
make: *** [all] Error 2

I think that's a linking problem with not being able to find libwsw and probably more specifically liblibwsw.a. So just wondering what I am doing wrong?

Build problems

NDL's picture

Hello Jeremy,

The last time I’ve touched this project was around 3 years ago so it’s quite possible there might be some problems with build using recent tools/compilers/libraries. Besides that I don’t think I’ve ever tested installation of libwsw/wswutil, moreover - I don’t remember if I’ve implemented appropriate commands in CMakeList.txt at all, so you might need to do things manually there. As far as I remember you shouldn’t copy libwsw to wswutil directory though - modifying WSW_INCLUDE_DIRS and WSW_LIBRARIES paths in CMakeCache.txt generated for wswutil project and re-running cmake should be enough for wswutil to find both libwsw includes and library file.

Syndicate content