<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Richard Jones, Esq. &#187; yaws</title>
	<atom:link href="http://www.metabrew.com/article/tag/yaws/feed" rel="self" type="application/rss+xml" />
	<link>http://www.metabrew.com</link>
	<description>Erlang, PHP, C, C++, Java, PostgreSQL, MySQL, Hadoop, Linux, awk, bash, sed, grep, screen, vim, irc, ssh etc...</description>
	<lastBuildDate>Sun, 20 Dec 2009 18:59:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Getting to know ejabberd and writing modules</title>
		<link>http://www.metabrew.com/article/getting-to-know-ejabberd-and-writing-modules/</link>
		<comments>http://www.metabrew.com/article/getting-to-know-ejabberd-and-writing-modules/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 21:53:17 +0000</pubDate>
		<dc:creator>RJ</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ejabberd]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[mnesia]]></category>
		<category><![CDATA[thrift]]></category>
		<category><![CDATA[xmpp]]></category>
		<category><![CDATA[yaws]]></category>

		<guid isPermaLink="false">http://www.metabrew.com/?p=203</guid>
		<description><![CDATA[I started poking around in the ejabberd source code to see what I could learn. I couldn&#8217;t find much in the way of high level documentation that talks about how the various bits of ejabberd talk to each other, so I&#8217;m starting to piece it together myself. After compiling ejabberd I made a php script [...]]]></description>
			<content:encoded><![CDATA[<p>I started poking around in the ejabberd source code to see what I could learn. I couldn&#8217;t find much in the way of high level documentation that talks about how the various bits of ejabberd talk to each other, so I&#8217;m starting to piece it together myself.</p>
<p>After compiling ejabberd I made a php script I could use with the external authentication system. Here&#8217;s a version that supports just two hardcoded users:</p>
<p>ejabberd.cfg:<br />
<code>{auth_method, external}.<br />
{extauth_program, "/tmp/auth.php"}.</code><br />
<br/></p>
<p>auth.php:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="co2">#!/usr/bin/php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$fh</span> &nbsp;= <a href="http://www.php.net/fopen"><span class="kw3">fopen</span></a><span class="br0">&#40;</span><span class="st0">&quot;php://stdin&quot;</span>, <span class="st0">&#8216;r&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$fh</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.php.net/die"><span class="kw3">die</span></a><span class="br0">&#40;</span><span class="st0">&quot;Cannot open STDIN<span class="es0">\n</span>&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$users</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;user1&#8242;</span>=&gt;<span class="st0">&#8216;password1&#8242;</span>, <span class="st0">&#8216;user2&#8242;</span>=&gt;<span class="st0">&#8216;password2&#8242;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">do</span><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$lenBytes</span> = <a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">&#40;</span><span class="re0">$fh</span>, <span class="nu0">3</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$len</span> = <a href="http://www.php.net/unpack"><span class="kw3">unpack</span></a><span class="br0">&#40;</span><span class="st0">&#8216;n&#8217;</span>, <span class="re0">$lenBytes</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$len</span> = <span class="re0">$len</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$len</span>&lt;<span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw1">continue</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> = <a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">&#40;</span><span class="re0">$fh</span>, <span class="re0">$len</span><span class="nu0">+1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$toks</span>=<a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">&#40;</span><span class="st0">&#8216;:&#8217;</span>,<span class="re0">$msg</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$method</span> = <a href="http://www.php.net/array_shift"><span class="kw3">array_shift</span></a><span class="br0">&#40;</span><span class="re0">$toks</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">switch</span><span class="br0">&#40;</span><span class="re0">$method</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;auth&#8217;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="re0">$username</span>, <span class="re0">$server</span>, <span class="re0">$password</span><span class="br0">&#41;</span> = <span class="re0">$toks</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>@<span class="re0">$users</span><span class="br0">&#91;</span><span class="re0">$username</span><span class="br0">&#93;</span> == <span class="re0">$password</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">&#40;</span><span class="st0">&quot;nn&quot;</span>, <span class="nu0">2</span>, <span class="nu0">1</span><span class="br0">&#41;</span>; <span class="co1">// ok</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="kw1">else</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">&#40;</span><span class="st0">&quot;nn&quot;</span>, <span class="nu0">2</span>, <span class="nu0">0</span><span class="br0">&#41;</span>; <span class="co1">// fail</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;isuser&#8217;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="re0">$username</span>, <span class="re0">$server</span><span class="br0">&#41;</span> = <span class="re0">$toks</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$users</span><span class="br0">&#91;</span><span class="re0">$username</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">&#40;</span><span class="st0">&quot;nn&quot;</span>, <span class="nu0">2</span>, <span class="nu0">1</span><span class="br0">&#41;</span>; <span class="co1">// yes</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="kw1">else</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">&#40;</span><span class="st0">&quot;nn&quot;</span>, <span class="nu0">2</span>, <span class="nu0">0</span><span class="br0">&#41;</span>; <span class="co1">// nope</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">default</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">&#40;</span><span class="st0">&quot;nn&quot;</span>, <span class="nu0">2</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;<span class="co1">// fail</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span><span class="kw1">while</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p> <br/></p>
<p>I stripped down the ejabberd config to just load what I considered the bare essentials. Here is the modules section I&#8217;m testing with:</p>
<p>From ejabberd.cfg:<br />
<code>{modules,<br />
 [<br />
  {mod_caps,     []},<br />
  {mod_disco,    []},<br />
  {mod_roster,   []},<br />
  {mod_pubsub,   [ % requires mod_caps<br />
                  {access_createnode, pubsub_createnode},<br />
                  {plugins, ["default", "pep"]}<br />
                 ]},<br />
  {mod_mnesiaweb,     []},<br />
  {mod_thriftctl,     []}<br />
 ]}.</code><br/></p>
<p>mod_disco deals with discovery, so clients can find out what the server supports. mod_roster deals with rosters (buddy lists etc) using mnesia. mod_pubsub is enabled because I want to use <a href="http://xmpp.org/extensions/xep-0118.html">User Tune</a>, an extension that lets you broadcast the name of the song you are playing to all everyone in your roster. mod_caps provides <a href="http://xmpp.org/extensions/xep-0115.html">XEP-115</a> &#8211; an extension for broadcasting and dynamically discovering client, device, or generic entity capabilities. mod_caps is a requirement of mod_pubsub.</p>
<p>I&#8217;ve removed the module that allows users to register, although I made a few accounts first whilst testing. The last two modules, mod_mnesiaweb and mod_thriftctl are modules I wrote.</p>
<h2>mod_mnesiaweb</h2>
<p>To help figure out what&#8217;s going on inside of ejabberd, it&#8217;s useful to be able to easily browse the mnesia database. <a href="http://yaws.hyber.org/">Yaws</a> comes with an appmod that does this, called ymnesia. This ejabberd module will start yaws in embedded mode and run this appmod, enabling you to explore the mnesia database from a web browser.</p>
<p><i><b>Yaws observation:</b> yaws didn&#8217;t appear to build ymnesia by default, I edited the Makefile in src and added &#8220;ymnesia&#8221; to the module list. Also, if ./configure fails, the package you are probably missing is libpam0g-dev</i></p>
<p>mod_mnesiaweb:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="co1">% Ejabberd module that runs yaws in embedded mode,</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% and loads the ymnesia appmod for browsing mnesia.</span></div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">module</span><span class="br0">&#40;</span>mod_mnesiaweb<span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">author</span><span class="br0">&#40;</span><span class="st0">&#8216;rj@last.fm&#8217;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;/usr/local/lib/yaws/include/yaws.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">behaviour</span><span class="br0">&#40;</span>gen_mod<span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">export</span><span class="br0">&#40;</span><span class="br0">&#91;</span>start/<span class="nu0">2</span>, stop/<span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">start<span class="br0">&#40;</span>_<span class="re0">Host</span>, <span class="re0">Opts</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Port</span> = gen_mod:<span class="me2">get_opt</span><span class="br0">&#40;</span>port, <span class="re0">Opts</span>, <span class="nu0">8001</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; code:<span class="me2">add_path</span><span class="br0">&#40;</span><span class="st0">&quot;/usr/local/lib/yaws/ebin&quot;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; application:<span class="me2">set_env</span><span class="br0">&#40;</span>yaws, embedded, true<span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; application:<span class="me2">start</span><span class="br0">&#40;</span>yaws<span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">GC</span> = yaws_config:<span class="me2">make_default_gconf</span><span class="br0">&#40;</span>false,<span class="st0">&quot;yawstest&quot;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">SC</span> = #sconf<span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; port = <span class="re0">Port</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; servername = <span class="st0">&quot;ejabnesia&quot;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">listen</span> = <span class="br0">&#123;</span><span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; appmods = <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;showdb&quot;</span>, ymnesia<span class="br0">&#125;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; docroot = <span class="st0">&quot;wwwroot&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; yaws_api:<span class="me2">setconf</span><span class="br0">&#40;</span><span class="re0">GC</span>, <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="re0">SC</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ok.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">stop<span class="br0">&#40;</span>_<span class="re0">Host</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="me1">application</span>:<span class="me2">stop</span><span class="br0">&#40;</span>yaws<span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ok.</div>
</li>
</ol>
</div>
<p><br/></p>
<p>To compile it:<br />
<code>erlc -pa ${EJAB_SRC} -I ${EJAB_SRC} mod_mnesiaweb.erl</code><br />
where EJAB_SRC is the ejabberd-2.X.X/src directory, after you&#8217;ve compiled from source (so the beams are there too).</p>
<p>Copy the resulting mod_mnesiaweb.beam to /var/lib/ejabberd/ebin so ejabberd finds it, and it should work. Hit up http://localhost:8001/showdb/ in your browser and you can explore the mnesia database.</p>
<p>Use the match syntax to filter tables. For example to find everyone in my roster, I use this in the input box next to roster:<br />
<code>{roster,{"RJ",'_', {'_','_',[]}}, '_','_','_','_','_','_','_','_'}</code><br/><br />
Not pretty, but it gets the job done. You can just view the entire table, copy a record then replace fields with &#8216;_&#8217; to build queries.</p>
<h2>mod_thriftctl</h2>
<p>Next up I wanted to try the Erlang <a href="http://incubator.apache.org/thrift/">Thrift</a> bindings (written by the folks at <a href="http://amiest-devblog.blogspot.com/2008/01/alternative-erlang-bindings-for-thrift.html">Amie St.</a>), and expose some useful functionality for controlling the server.</p>
<p>If you aren&#8217;t familiar with Thrift, I recommend reading about it first. In a nutshell, you write your API using an IDL (a .thrift file) and the thrift compiler creates client libraries, and server code in various different languages. It&#8217;s an RPC mechanism, and useful in a mixed environment.</p>
<p>mod_thriftctl.thrift:<br />
<code>#!/usr/local/bin/thrift -php -erl</p>
<p>struct JabberUser {<br />
    1: string name,<br />
    2: string server<br />
}</p>
<p>service Ejabthrift {<br />
    /* add ruser to roster of luser, and visa-versa. also routes presence to users if online  */<br />
    void add_friend(        1: JabberUser luser,<br />
                            2: JabberUser ruser<br />
                            ),</p>
<p>    /* remove ruser from luser's roster */<br />
    void remove_friend(    1: JabberUser luser, 2: JabberUser ruser ),</p>
<p>    /* make it look like fromuser sent a message to touser */<br />
    void spoof_message( 1: JabberUser fromuser, 2: JabberUser touser, 3: string message, 4: string subject ),<br />
    /* .. or a chat message */<br />
    void spoof_chat(    1: JabberUser fromuser, 2: JabberUser touser, 3: string message, 4: string thread ),</p>
<p>    /* sends PEP usertune message, see http://xmpp.org/extensions/xep-0118.html */<br />
    void publish_np ( 1: JabberUser fromuser, 2: string artist, 3: string album, 4: string track, 5: i32 tracklength, 6: i32 tracknum )<br />
}</code><br/></p>
<p>Run that .thrift file, and you get gen-php and gen-erl directories, with php client code, and erlang files needed to build a server. </p>
<p>Here&#8217;s the ejabberd module, which starts a thrift server:</p>
<p>mod_thriftctl:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="co1">%</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% A module to control ejabberd with a thrift interface.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">%</span></div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">module</span><span class="br0">&#40;</span>mod_thriftctl<span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">-<span class="kw2">author</span><span class="br0">&#40;</span><span class="st0">&#8216;rj@last.fm&#8217;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% ejabberd headers:</span></div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;ejabberd.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;mod_roster.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">-include<span class="br0">&#40;</span><span class="st0">&quot;jlib.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% thrift server headers:</span></div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;thrift.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;transport/tSocket.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">-include<span class="br0">&#40;</span><span class="st0">&quot;protocol/tBinaryProtocol.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;server/tErlServer.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;transport/tErlAcceptor.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% we are an ejabberd module:</span></div>
</li>
<li class="li2">
<div class="de2">-<span class="kw2">behaviour</span><span class="br0">&#40;</span>gen_mod<span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">export</span><span class="br0">&#40;</span><span class="br0">&#91;</span>start/<span class="nu0">2</span>, stop/<span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% our thrift service:</span></div>
</li>
<li class="li1">
<div class="de1">-include<span class="br0">&#40;</span><span class="st0">&quot;ejabthrift_thrift.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">-include<span class="br0">&#40;</span><span class="st0">&quot;mod_thriftctl_types.hrl&quot;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">-<span class="kw2">export</span><span class="br0">&#40;</span><span class="br0">&#91;</span> &nbsp; add_friend/<span class="nu0">2</span>, remove_friend/<span class="nu0">2</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spoof_message/<span class="nu0">4</span>, spoof_chat/<span class="nu0">4</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publish_np/<span class="nu0">6</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#93;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% convert thrift Jabberuser into ejabberd jid</span></div>
</li>
<li class="li1">
<div class="de1">ju2jid<span class="br0">&#40;</span><span class="re0">Jabberuser</span><span class="br0">&#41;</span> when is_record<span class="br0">&#40;</span><span class="re0">Jabberuser</span>, jabber<span class="re0">User</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; #jid<span class="br0">&#123;</span> user=<span class="re0">Jabberuser</span>#jabber<span class="re0">User</span>.name, server=<span class="re0">Jabberuser</span>#jabber<span class="re0">User</span>.server, resource=<span class="st0">&quot;&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; luser=<span class="re0">Jabberuser</span>#jabber<span class="re0">User</span>.name, lserver=<span class="re0">Jabberuser</span>#jabber<span class="re0">User</span>.server, lresource=<span class="st0">&quot;&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">spoof_message<span class="br0">&#40;</span> <span class="re0">FromU</span>, <span class="re0">ToU</span>, <span class="re0">Msg</span>, <span class="re0">Subject</span> <span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">F</span> = ju2jid<span class="br0">&#40;</span><span class="re0">FromU</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">T</span> = ju2jid<span class="br0">&#40;</span><span class="re0">ToU</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">XmlBody</span> = <span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;message&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#91;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">&quot;from&quot;</span>, jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">F</span><span class="br0">&#41;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">&quot;to&quot;</span>, jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">T</span><span class="br0">&#41;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#93;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#91;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;subject&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Subject</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;body&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Msg</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ejabberd_router:<span class="me2">route</span><span class="br0">&#40;</span><span class="re0">F</span>, <span class="re0">T</span>, <span class="re0">XmlBody</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">spoof_chat<span class="br0">&#40;</span> <span class="re0">FromU</span>, <span class="re0">ToU</span>, <span class="re0">Msg</span>, <span class="re0">Thread</span> <span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">F</span> = ju2jid<span class="br0">&#40;</span><span class="re0">FromU</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">T</span> = ju2jid<span class="br0">&#40;</span><span class="re0">ToU</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">XmlBody</span> = <span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;message&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;type&quot;</span>, <span class="st0">&quot;chat&quot;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">&quot;from&quot;</span>, jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">F</span><span class="br0">&#41;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">&quot;to&quot;</span>, jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">T</span><span class="br0">&#41;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#93;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#91;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;thread&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Thread</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;body&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Msg</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ejabberd_router:<span class="me2">route</span><span class="br0">&#40;</span><span class="re0">F</span>, <span class="re0">T</span>, <span class="re0">XmlBody</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">publish_np<span class="br0">&#40;</span> <span class="re0">FromU</span>, <span class="re0">ArtistS</span>, <span class="re0">AlbumS</span>, <span class="re0">TrackS</span>, <span class="re0">LengthI</span>, <span class="re0">TrackNumI</span> <span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">From</span> = ju2jid<span class="br0">&#40;</span><span class="re0">FromU</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">% The usertune message must contain binaries, not strings or ints</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">FromStr</span> &nbsp; &nbsp; = jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">From</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Artist</span> &nbsp; &nbsp; &nbsp;= list_to_binary<span class="br0">&#40;</span><span class="re0">ArtistS</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Album</span> &nbsp; &nbsp; &nbsp; = list_to_binary<span class="br0">&#40;</span><span class="re0">AlbumS</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Track</span> &nbsp; &nbsp; &nbsp; = list_to_binary<span class="br0">&#40;</span><span class="re0">TrackS</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Length</span> &nbsp; &nbsp; &nbsp;= list_to_binary<span class="br0">&#40;</span>io_lib:<span class="kw3">format</span><span class="br0">&#40;</span><span class="st0">&quot;~w&quot;</span>,<span class="br0">&#91;</span><span class="re0">LengthI</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">TrackNum</span> &nbsp; &nbsp;= list_to_binary<span class="br0">&#40;</span>io_lib:<span class="kw3">format</span><span class="br0">&#40;</span><span class="st0">&quot;~w&quot;</span>,<span class="br0">&#91;</span><span class="re0">TrackNumI</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Xml</span> = <span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;iq&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;from&quot;</span>, <span class="re0">FromStr</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span><span class="st0">&quot;type&quot;</span>,<span class="st0">&quot;set&quot;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span><span class="st0">&quot;id&quot;</span>,<span class="st0">&quot;pub1&quot;</span><span class="br0">&#125;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;pubsub&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;xmlns&quot;</span>,<span class="st0">&quot;http://jabber.org/protocol/pubsub&quot;</span><span class="br0">&#125;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;publish&quot;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;node&quot;</span>,<span class="st0">&quot;http://jabber.org/protocol/tune&quot;</span><span class="br0">&#125;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;item&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;tune&quot;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;xmlns&quot;</span>,<span class="st0">&quot;http://jabber.org/protocol/tune&quot;</span><span class="br0">&#125;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;artist&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Artist</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;length&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span>,<span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Length</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;source&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Album</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;title&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Track</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlelement,<span class="st0">&quot;track&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span>,<span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">TrackNum</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp; &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span> &nbsp;&quot;</span>&gt;&gt;<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>xmlcdata,&lt;&lt;<span class="st0">&quot;<span class="es0">\n</span>&quot;</span>&gt;&gt;<span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">% PEP means you act as a pubsub node yourself,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">% so it&#8217;s addressed to yourself and is broadcast to your friends automatically:</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ejabberd_router:<span class="me2">route</span><span class="br0">&#40;</span><span class="re0">From</span>, <span class="re0">From</span>, <span class="re0">Xml</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ok.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">% adds bi-directional friend relationship immediately for both users.</span></div>
</li>
<li class="li2">
<div class="de2">add_friend<span class="br0">&#40;</span> &nbsp; &nbsp; #jabber<span class="re0">User</span><span class="br0">&#123;</span>name=<span class="re0">LU</span>, server=<span class="re0">LS</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #jabber<span class="re0">User</span><span class="br0">&#123;</span>name=<span class="re0">RU</span>, server=<span class="re0">RS</span><span class="br0">&#125;</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">AskMessage</span> = <span class="st0">&quot;&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Group</span> = <span class="st0">&quot;&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Subtype</span> = both,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; subscribe<span class="br0">&#40;</span><span class="re0">LU</span>, <span class="re0">LS</span>, <span class="re0">RU</span>, <span class="re0">RS</span>, <span class="re0">RU</span>, <span class="re0">Group</span>, <span class="re0">Subtype</span>, <span class="re0">AskMessage</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; subscribe<span class="br0">&#40;</span><span class="re0">RU</span>, <span class="re0">RS</span>, <span class="re0">LU</span>, <span class="re0">LS</span>, <span class="re0">LU</span>, <span class="re0">Group</span>, <span class="re0">Subtype</span>, <span class="re0">AskMessage</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; route_rosteritem<span class="br0">&#40;</span><span class="re0">LU</span>, <span class="re0">LS</span>, <span class="re0">RU</span>, <span class="re0">RS</span>, <span class="re0">RU</span>, <span class="re0">Group</span>, <span class="re0">Subtype</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; route_rosteritem<span class="br0">&#40;</span><span class="re0">RU</span>, <span class="re0">RS</span>, <span class="re0">LU</span>, <span class="re0">LS</span>, <span class="re0">LU</span>, <span class="re0">Group</span>, <span class="re0">Subtype</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ok.</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">remove_friend<span class="br0">&#40;</span> #jabber<span class="re0">User</span><span class="br0">&#123;</span>name=<span class="re0">LU</span>, server=<span class="re0">LS</span><span class="br0">&#125;</span>, #jabber<span class="re0">User</span><span class="br0">&#123;</span>name=<span class="re0">RU</span>, server=<span class="re0">RS</span><span class="br0">&#125;</span> <span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="me1">unsubscribe</span><span class="br0">&#40;</span><span class="re0">LU</span>, <span class="re0">LS</span>, <span class="re0">RU</span>, <span class="re0">RS</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; unsubscribe<span class="br0">&#40;</span><span class="re0">RU</span>, <span class="re0">RS</span>, <span class="re0">LU</span>, <span class="re0">LS</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; route_rosteritem<span class="br0">&#40;</span><span class="re0">LU</span>, <span class="re0">LS</span>, <span class="re0">RU</span>, <span class="re0">RS</span>, <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;remove&quot;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; route_rosteritem<span class="br0">&#40;</span><span class="re0">RU</span>, <span class="re0">RS</span>, <span class="re0">LU</span>, <span class="re0">LS</span>, <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;remove&quot;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ok.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">unsubscribe<span class="br0">&#40;</span><span class="re0">LocalUser</span>, <span class="re0">LocalServer</span>, <span class="re0">RemoteUser</span>, <span class="re0">RemoteServer</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Key</span> = <span class="br0">&#123;</span><span class="br0">&#123;</span><span class="re0">LocalUser</span>,<span class="re0">LocalServer</span>,<span class="br0">&#123;</span><span class="re0">RemoteUser</span>,<span class="re0">RemoteServer</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#125;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span><span class="re0">LocalUser</span>,<span class="re0">LocalServer</span><span class="br0">&#125;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; mnesia:<span class="me2">transaction</span><span class="br0">&#40;</span>fun<span class="br0">&#40;</span><span class="br0">&#41;</span> -&gt; <span class="me1">mnesia</span>:<span class="me2">delete</span><span class="br0">&#40;</span>roster, <span class="re0">Key</span>, write<span class="br0">&#41;</span> <span class="kw1">end</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">route_rosteritem<span class="br0">&#40;</span><span class="re0">LocalUser</span>, <span class="re0">LocalServer</span>, <span class="re0">RemoteUser</span>, <span class="re0">RemoteServer</span>, <span class="re0">Nick</span>, <span class="re0">Group</span>, <span class="re0">Subscription</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">LJID</span> = jlib:<span class="me2">make_jid</span><span class="br0">&#40;</span><span class="re0">LocalUser</span>, <span class="re0">LocalServer</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">RJID</span> = jlib:<span class="me2">make_jid</span><span class="br0">&#40;</span><span class="re0">RemoteUser</span>, <span class="re0">RemoteServer</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">ToS</span> = jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">LJID</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">ItemJIDS</span> = jlib:<span class="me2">jid_to_string</span><span class="br0">&#40;</span><span class="re0">RJID</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">GroupXML</span> = <span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;group&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span>xmlcdata, <span class="re0">Group</span><span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Item</span> = <span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;item&quot;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;jid&quot;</span>, <span class="re0">ItemJIDS</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span><span class="st0">&quot;name&quot;</span>, <span class="re0">Nick</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span><span class="st0">&quot;subscription&quot;</span>, <span class="re0">Subscription</span><span class="br0">&#125;</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="re0">GroupXML</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Query</span> = <span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;query&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;xmlns&quot;</span>, ?<span class="re0">NS_ROSTER</span><span class="br0">&#125;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="re0">Item</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">Packet</span> = <span class="br0">&#123;</span>xmlelement, <span class="st0">&quot;iq&quot;</span>, <span class="br0">&#91;</span><span class="br0">&#123;</span><span class="st0">&quot;type&quot;</span>, <span class="st0">&quot;set&quot;</span><span class="br0">&#125;</span>, <span class="br0">&#123;</span><span class="st0">&quot;to&quot;</span>, <span class="re0">ToS</span><span class="br0">&#125;</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="re0">Query</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ejabberd_router:<span class="me2">route</span><span class="br0">&#40;</span><span class="re0">LJID</span>, <span class="re0">LJID</span>, <span class="re0">Packet</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">subscribe<span class="br0">&#40;</span><span class="re0">LocalUser</span>, <span class="re0">LocalServer</span>, <span class="re0">RemoteUser</span>, <span class="re0">RemoteServer</span>, <span class="re0">Nick</span>, <span class="re0">Group</span>, <span class="re0">Subscription</span>, <span class="re0">Xattrs</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">R</span> = #roster<span class="br0">&#123;</span>usj = <span class="br0">&#123;</span><span class="re0">LocalUser</span>,<span class="re0">LocalServer</span>,<span class="br0">&#123;</span><span class="re0">RemoteUser</span>,<span class="re0">RemoteServer</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#125;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; us = <span class="br0">&#123;</span><span class="re0">LocalUser</span>,<span class="re0">LocalServer</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jid = <span class="br0">&#123;</span><span class="re0">RemoteUser</span>,<span class="re0">RemoteServer</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#125;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name = <span class="re0">Nick</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; subscription = <span class="re0">Subscription</span>, <span class="co1">% none, to=you see him, from=he sees you, both</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ask = none, <span class="co1">% out=send request, in=somebody requests you, none</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; groups = <span class="br0">&#91;</span><span class="re0">Group</span><span class="br0">&#93;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; askmessage = <span class="re0">Xattrs</span>, <span class="co1">% example: [{&quot;category&quot;,&quot;conference&quot;}]</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xs = <span class="br0">&#91;</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; mnesia:<span class="me2">transaction</span><span class="br0">&#40;</span>fun<span class="br0">&#40;</span><span class="br0">&#41;</span> -&gt; <span class="me1">mnesia</span>:<span class="me2">write</span><span class="br0">&#40;</span><span class="re0">R</span><span class="br0">&#41;</span> <span class="kw1">end</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">start<span class="br0">&#40;</span><span class="re0">Host</span>, <span class="re0">Opts</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ?<span class="re0">INFO</span><span class="br0">&#40;</span><span class="st0">&quot;mod_ejabthrift start().&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">%% get options</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">Port</span> = gen_mod:<span class="me2">get_opt</span><span class="br0">&#40;</span>port, <span class="re0">Opts</span>, <span class="nu0">9000</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; spawn<span class="br0">&#40;</span>fun<span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt; <span class="me1">thrift</span>:<span class="me2">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">end</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ?<span class="re0">INFO</span><span class="br0">&#40;</span><span class="st0">&quot;mod_ejabthrift thrift:start().&quot;</span>,<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">Handler</span> &nbsp; = ?<span class="re0">MODULE</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Processor</span> = ejabthrift_thrift,</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">TF</span> = t<span class="re0">BufferedTransportFactory</span>:<span class="me2">new</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">PF</span> = t<span class="re0">BinaryProtocolFactory</span>:<span class="me2">new</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">ServerTransport</span> = t<span class="re0">ErlAcceptor</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">ServerFlavor</span> &nbsp; &nbsp;= t<span class="re0">ErlServer</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Server</span> = oop:<span class="me2">start_new</span><span class="br0">&#40;</span><span class="re0">ServerFlavor</span>, <span class="br0">&#91;</span><span class="re0">Port</span>, <span class="re0">Handler</span>, <span class="re0">Processor</span>, <span class="re0">ServerTransport</span>, <span class="re0">TF</span>, <span class="re0">PF</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">case</span> ?<span class="re0">R0</span><span class="br0">&#40;</span><span class="re0">Server</span>, effectful_serve<span class="br0">&#41;</span> <span class="kw1">of</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ok &nbsp; &nbsp;-&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; ?<span class="re0">INFO</span><span class="br0">&#40;</span><span class="st0">&quot;mod_ejabthrift: Thrift server (~s) listening on port ~w&quot;</span>,<span class="br0">&#91;</span><span class="re0">Host</span>, <span class="re0">Port</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">% put Server into process dictionary (needed for clean stop)</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; put<span class="br0">&#40;</span>thrift_server_reference, <span class="re0">Server</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; ok;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">Error</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; ?<span class="re0">ERROR_MSG</span><span class="br0">&#40;</span><span class="st0">&quot;mod_ejabthrift: Error starting thrift server: ~w&quot;</span>, <span class="br0">&#91;</span><span class="re0">Error</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">Error</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">end</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">stop<span class="br0">&#40;</span>_<span class="re0">Host</span><span class="br0">&#41;</span> -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ?<span class="re0">C0</span><span class="br0">&#40;</span>get<span class="br0">&#40;</span>thrift_server_reference<span class="br0">&#41;</span>, stop<span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ok.</div>
</li>
</ol>
</div>
<p><br/></p>
<p>To build, first build the gen-erl code:</p>
<p><code>erlc -pa ${EJAB_SRC} -I ${EJAB_SRC} -I ${ERL_THRIFT}/include -I ./gen-erl -o ./gen-erl ./gen-erl/*.erl</code></p>
<p>Where ERL_THRIFT is the lib/erl directory from the amiethrift code, git://repo.or.cz/amiethrift.git</p>
<p>Then compile the module:</p>
<p><code>erlc -pa ${EJAB_SRC} -I ${EJAB_SRC} -I ${ERL_THRIFT}/include -I ./gen-erl *.erl</code></p>
<p>To install, copy all the beam files to the ejabberd ebin dir:</p>
<p><code>sudo cp *.beam gen-erl/*.beam /var/lib/ejabberd/ebin/</code></p>
<p>This is inspired by mod_xmlrpc, which is in ejabberd-modules. As you can see from the start function, that&#8217;s what it takes to start a thrift server. It&#8217;s now trivial to call into ejabberd from other languages. For example, if you started listening to a song using a flash player on the website, a php webservice could make a user tune announcement on your behalf, or spoof messages from you boasting how much you love listening to Paris Hilton. </p>
<p>If anyone knows where I can read about the ejabberd architecture / design, so I don&#8217;t have to piece it all together myself, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.metabrew.com/article/getting-to-know-ejabberd-and-writing-modules//feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
