<!DOCTYPE html>
<html lang='en'>
<head>
<title>Merge branch 'master' into otr - profani-tty - Profanity fork with TTY improvements</title>
<meta name='generator' content='cgit 1.4.1-2-gfad0'/>
<meta name='robots' content='index, nofollow'/>
<link rel='stylesheet' type='text/css' href='/cgit.css'/>
<link rel='alternate' title='Atom feed' href='https://git.tilde.institute/danisanti/profani-tty/atom/src?h=main' type='application/atom+xml'/>
<link rel='vcs-git' href='https://git.tilde.institute/danisanti/profani-tty' title='profani-tty Git repository'/>
</head>
<body>
<div id='cgit'><table id='header'>
<tr>
<td class='main'><a href='/'>index</a> : <a href='/danisanti/profani-tty/'>profani-tty</a></td><td class='form'><form method='get'>
<input type='hidden' name='id' value='2470f642c73a7b13181bf51a6f3c2ee126e9e733'/><select name='h' onchange='this.form.submit();'>
<option value='953e3cc1204cde0f59c0d1230694b5ad5682c698'>this commit</option>
<optgroup label='branches'><option value='main' selected='selected'>main</option>
</optgroup></select> <input type='submit' value='switch'/></form></td></tr>
<tr><td class='sub'>Profanity fork with TTY improvements</td><td class='sub right'>danisanti &lt;danisanti@tilde.institute&gt;</td></tr></table>
<table class='tabs'><tr><td>
<a href='/danisanti/profani-tty/about/'>about</a> <a href='/danisanti/profani-tty/'>summary</a> <a href='/danisanti/profani-tty/refs/?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>refs</a> <a href='/danisanti/profani-tty/log/src'>log</a> <a href='/danisanti/profani-tty/tree/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>tree</a> <a class='active' href='/danisanti/profani-tty/commit/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>commit</a> <a href='/danisanti/profani-tty/diff/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>diff</a> <a href='/danisanti/profani-tty/stats/src'>stats</a></td><td class='form'><form class='right' method='get' action='/danisanti/profani-tty/log/src'>
<input type='hidden' name='id' value='2470f642c73a7b13181bf51a6f3c2ee126e9e733'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/danisanti/profani-tty/commit/?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>root</a>/<a href='/danisanti/profani-tty/commit/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src</a></div><div class='content'><div class='cgit-panel'><b>diff options</b><form method='get'><input type='hidden' name='id' value='2470f642c73a7b13181bf51a6f3c2ee126e9e733'/><table><tr><td colspan='2'/></tr><tr><td class='label'>context:</td><td class='ctrl'><select name='context' onchange='this.form.submit();'><option value='1'>1</option><option value='2'>2</option><option value='3' selected='selected'>3</option><option value='4'>4</option><option value='5'>5</option><option value='6'>6</option><option value='7'>7</option><option value='8'>8</option><option value='9'>9</option><option value='10'>10</option><option value='15'>15</option><option value='20'>20</option><option value='25'>25</option><option value='30'>30</option><option value='35'>35</option><option value='40'>40</option></select></td></tr><tr><td class='label'>space:</td><td class='ctrl'><select name='ignorews' onchange='this.form.submit();'><option value='0' selected='selected'>include</option><option value='1'>ignore</option></select></td></tr><tr><td class='label'>mode:</td><td class='ctrl'><select name='dt' onchange='this.form.submit();'><option value='0' selected='selected'>unified</option><option value='1'>ssdiff</option><option value='2'>stat only</option></select></td></tr><tr><td/><td class='ctrl'><noscript><input type='submit' value='reload'/></noscript></td></tr></table></form></div><table summary='commit info' class='commit-info'>
<tr><th>author</th><td>James Booth &lt;boothj5@gmail.com&gt;</td><td class='right'>2013-12-15 17:19:01 +0000</td></tr>
<tr><th>committer</th><td>James Booth &lt;boothj5@gmail.com&gt;</td><td class='right'>2013-12-15 17:19:01 +0000</td></tr>
<tr><th>commit</th><td colspan='2' class='oid'><a href='/danisanti/profani-tty/commit/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>2470f642c73a7b13181bf51a6f3c2ee126e9e733</a> (<a href='/danisanti/profani-tty/patch/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>patch</a>)</td></tr>
<tr><th>tree</th><td colspan='2' class='oid'><a href='/danisanti/profani-tty/tree/?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>d578411bda883f02e3c7cc4d256bb5a96c5034bf</a> /<a href='/danisanti/profani-tty/tree/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src</a></td></tr>
<tr><th>parent</th><td colspan='2' class='oid'><a href='/danisanti/profani-tty/commit/src?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>06367723d7b97abe1958944b651cdbbf9b5c856a</a> (<a href='/danisanti/profani-tty/diff/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733&amp;id2=06367723d7b97abe1958944b651cdbbf9b5c856a'>diff</a>)</td></tr><tr><th>parent</th><td colspan='2' class='oid'><a href='/danisanti/profani-tty/commit/src?id=2490f5b417a13639771211a7862bab88a6a5195e'>2490f5b417a13639771211a7862bab88a6a5195e</a> (<a href='/danisanti/profani-tty/diff/src?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733&amp;id2=2490f5b417a13639771211a7862bab88a6a5195e'>diff</a>)</td></tr><tr><th>download</th><td colspan='2' class='oid'><a href='/danisanti/profani-tty/snapshot/profani-tty-2470f642c73a7b13181bf51a6f3c2ee126e9e733.tar.gz'>profani-tty-2470f642c73a7b13181bf51a6f3c2ee126e9e733.tar.gz</a><br/></td></tr></table>
<div class='commit-subject'>Merge branch 'master' into otr</div><pre class='commit-msg'>Conflicts:
	src/command/command.c
</pre><div class='diffstat-header'><a href='/danisanti/profani-tty/diff/?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>Diffstat</a> (limited to 'src')</div><table summary='diffstat' class='diffstat'><tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/command/command.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/command.c</a></td><td class='right'>2580</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 2.4%;'/><td class='rem' style='width: 97.6%;'/><td class='none' style='width: 0.0%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/command/command.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/command.h</a></td><td class='right'>9</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 0.1%;'/><td class='rem' style='width: 0.3%;'/><td class='none' style='width: 99.7%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/danisanti/profani-tty/diff/src/command/commands.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/commands.c</a></td><td class='right'>2409</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 93.4%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 6.6%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/danisanti/profani-tty/diff/src/command/commands.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/commands.h</a></td><td class='right'>113</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 4.4%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 95.6%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/contact.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/contact.c</a></td><td class='right'>25</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 1.0%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 99.0%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/contact.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/contact.h</a></td><td class='right'>1</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 0.0%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 100.0%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/profanity.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/profanity.c</a></td><td class='right'>34</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 1.1%;'/><td class='rem' style='width: 0.2%;'/><td class='none' style='width: 98.7%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/danisanti/profani-tty/diff/src/roster_list.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/roster_list.c</a></td><td class='right'>475</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 18.4%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 81.6%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/danisanti/profani-tty/diff/src/roster_list.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/roster_list.h</a></td><td class='right'>58</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 2.2%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 97.8%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/ui/console.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/console.c</a></td><td class='right'>159</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 3.0%;'/><td class='rem' style='width: 3.1%;'/><td class='none' style='width: 93.8%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/ui/core.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/core.c</a></td><td class='right'>334</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add' style='width: 2.4%;'/><td class='rem' style='width: 10.5%;'/><td class='none' style='width: 87.1%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/danisanti/profani-tty/diff/src/ui/inputwin.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/inputwin.c</a></td><td class='right'>1</td><td class='graph'><table summary='file diffstat' width='100%'><tr><td class='add<style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span>/*<span class="w"> </span>Table<span class="w"> </span>of<span class="w"> </span>DBX<span class="w"> </span>symbol<span class="w"> </span>codes<span class="w"> </span>for<span class="w"> </span>the<span class="w"> </span>GNU<span class="w"> </span>system.
<span class="w">   </span>Copyright<span class="w"> </span>(C)<span class="w"> </span><span class="m">1988</span>,<span class="w"> </span><span class="m">1997</span><span class="w"> </span>Free<span class="w"> </span>Software<span class="w"> </span>Foundation,<span class="w"> </span>Inc.
<span class="w">   </span>This<span class="w"> </span>file<span class="w"> </span>is<span class="w"> </span>part<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>GNU<span class="w"> </span>C<span class="w"> </span>Library.

<span class="w">   </span>The<span class="w"> </span>GNU<span class="w"> </span>C<span class="w"> </span>Library<span class="w"> </span>is<span class="w"> </span>free<span class="w"> </span>software;<span class="w"> </span>you<span class="w"> </span>can<span class="w"> </span>redistribute<span class="w"> </span>it<span class="w"> </span>and/or
<span class="w">   </span>modify<span class="w"> </span>it<span class="w"> </span>under<span class="w"> </span>the<span class="w"> </span>terms<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>GNU<span class="w"> </span>Library<span class="w"> </span>General<span class="w"> </span>Public<span class="w"> </span>License<span class="w"> </span>as
<span class="w">   </span>published<span class="w"> </span>by<span class="w"> </span>the<span class="w"> </span>Free<span class="w"> </span>Software<span class="w"> </span>Foundation;<span class="w"> </span>either<span class="w"> </span>version<span class="w"> </span><span class="m">2</span><span class="w"> </span>of<span class="w"> </span>the
<span class="w">   </span>License,<span class="w"> </span>or<span class="w"> </span>(at<span class="w"> </span>your<span class="w"> </span>option)<span class="w"> </span>any<span class="w"> </span>later<span class="w"> </span>version.

<span class="w">   </span>The<span class="w"> </span>GNU<span class="w"> </span>C<span class="w"> </span>Library<span class="w"> </span>is<span class="w"> </span>distributed<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>hope<span class="w"> </span>that<span class="w"> </span>it<span class="w"> </span>will<span class="w"> </span>be<span class="w"> </span>useful,
<span class="w">   </span>but<span class="w"> </span>WITHOUT<span class="w"> </span>ANY<span class="w"> </span>WARRANTY;<span class="w"> </span>without<span class="w"> </span>even<span class="w"> </span>the<span class="w"> </span>implied<span class="w"> </span>warranty<span class="w"> </span>of
<span class="w">   </span>MERCHANTABILITY<span class="w"> </span>or<span class="w"> </span>FITNESS<span class="w"> </span>FOR<span class="w"> </span>A<span class="w"> </span>PARTICULAR<span class="w"> </span>PURPOSE.<span class="w">  </span>See<span class="w"> </span>the<span class="w"> </span>GNU
<span class="w">   </span>Library<span class="w"> </span>General<span class="w"> </span>Public<span class="w"> </span>License<span class="w"> </span>for<span class="w"> </span>more<span class="w"> </span>details.

<span class="w">   </span>You<span class="w"> </span>should<span class="w"> </span>have<span class="w"> </span>received<span class="w"> </span>a<span class="w"> </span>copy<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>GNU<span class="w"> </span>Library<span class="w"> </span>General<span class="w"> </span>Public
<span class="w">   </span>License<span class="w"> </span>along<span class="w"> </span>with<span class="w"> </span>the<span class="w"> </span>GNU<span class="w"> </span>C<span class="w"> </span>Library;<span class="w"> </span>see<span class="w"> </span>the<span class="w"> </span>file<span class="w"> </span>COPYING.LIB.<span class="w">  </span>If<span class="w"> </span>not,
<span class="w">   </span>write<span class="w"> </span>to<span class="w"> </span>the<span class="w"> </span>Free<span class="w"> </span>Software<span class="w"> </span>Foundation,<span class="w"> </span>Inc.,<span class="w"> </span><span class="m">59</span><span class="w"> </span>Temple<span class="w"> </span>Place<span class="w"> </span>-<span class="w"> </span>Suite<span class="w"> </span><span class="m">330</span>,
<span class="w">   </span>Boston,<span class="w"> </span>MA<span class="w"> </span><span class="m">02111</span>-<span class="m">1307</span>,<span class="w"> </span>USA.<span class="w">  </span>*/

/*<span class="w"> </span>This<span class="w"> </span>contains<span class="w"> </span>contribution<span class="w"> </span>from<span class="w"> </span>Cygnus<span class="w"> </span>Support.<span class="w">  </span>*/

/*<span class="w"> </span>Global<span class="w"> </span>variable.<span class="w">  </span>Only<span class="w"> </span>the<span class="w"> </span>name<span class="w"> </span>is<span class="w"> </span>significant.
<span class="w">   </span>To<span class="w"> </span>find<span class="w"> </span>the<span class="w"> </span>address,<span class="w"> </span>look<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>corresponding<span class="w"> </span>external<span class="w"> </span>symbol.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_GSYM,<span class="w"> </span>0x20,<span class="w"> </span>&quot;GSYM&quot;)

/*<span class="w"> </span>Function<span class="w"> </span>name<span class="w"> </span>for<span class="w"> </span>BSD<span class="w"> </span>Fortran.<span class="w">  </span>Only<span class="w"> </span>the<span class="w"> </span>name<span class="w"> </span>is<span class="w"> </span>significant.
<span class="w">   </span>To<span class="w"> </span>find<span class="w"> </span>the<span class="w"> </span>address,<span class="w"> </span>look<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>corresponding<span class="w"> </span>external<span class="w"> </span>symbol.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_FNAME,<span class="w"> </span>0x22,<span class="w"> </span>&quot;FNAME&quot;)

/*<span class="w"> </span>Function<span class="w"> </span>name<span class="w"> </span>or<span class="w"> </span>text-segment<span class="w"> </span>variable<span class="w"> </span>for<span class="w"> </span>C.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>its<span class="w"> </span>address.
<span class="w">   </span>Desc<span class="w"> </span>is<span class="w"> </span>supposedly<span class="w"> </span>starting<span class="w"> </span>line<span class="w"> </span>number,<span class="w"> </span>but<span class="w"> </span>GCC<span class="w"> </span>doesn&#39;t<span class="w"> </span>set<span class="w"> </span>it
<span class="w">   </span>and<span class="w"> </span>DBX<span class="w"> </span>seems<span class="w"> </span>not<span class="w"> </span>to<span class="w"> </span>miss<span class="w"> </span>it.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_FUN,<span class="w"> </span>0x24,<span class="w"> </span>&quot;FUN&quot;)

/*<span class="w"> </span>Data-segment<span class="w"> </span>variable<span class="w"> </span>with<span class="w"> </span>internal<span class="w"> </span>linkage.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>its<span class="w"> </span>address.
<span class="w">   </span>&quot;Static<span class="w"> </span>Sym&quot;.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_STSYM,<span class="w"> </span>0x26,<span class="w"> </span>&quot;STSYM&quot;)

/*<span class="w"> </span>BSS-segment<span class="w"> </span>variable<span class="w"> </span>with<span class="w"> </span>internal<span class="w"> </span>linkage.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>its<span class="w"> </span>address.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_LCSYM,<span class="w"> </span>0x28,<span class="w"> </span>&quot;LCSYM&quot;)

/*<span class="w"> </span>Name<span class="w"> </span>of<span class="w"> </span>main<span class="w"> </span>routine.<span class="w">  </span>Only<span class="w"> </span>the<span class="w"> </span>name<span class="w"> </span>is<span class="w"> </span>significant.
<span class="w">   </span>This<span class="w"> </span>is<span class="w"> </span>not<span class="w"> </span>used<span class="w"> </span>in<span class="w"> </span>C.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_MAIN,<span class="w"> </span>0x2a,<span class="w"> </span>&quot;MAIN&quot;)

/*<span class="w"> </span>Global<span class="w"> </span>symbol<span class="w"> </span>in<span class="w"> </span>Pascal.
<span class="w">   </span>Supposedly<span class="w"> </span>the<span class="w"> </span>value<span class="w"> </span>is<span class="w"> </span>its<span class="w"> </span>line<span class="w"> </span>number;<span class="w"> </span>I&#39;m<span class="w"> </span>skeptical.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_PC,<span class="w"> </span>0x30,<span class="w"> </span>&quot;PC&quot;)

/*<span class="w"> </span>Number<span class="w"> </span>of<span class="w"> </span>symbols:<span class="w">  </span><span class="m">0</span>,<span class="w"> </span>files,,funcs,lines<span class="w"> </span>according<span class="w"> </span>to<span class="w"> </span>Ultrix<span class="w"> </span>V4<span class="m">.0</span>.<span class="w"> </span>*/
__define_stab<span class="w"> </span>(N_NSYMS,<span class="w"> </span>0x32,<span class="w"> </span>&quot;NSYMS&quot;)

/*<span class="w"> </span>&quot;No<span class="w"> </span>DST<span class="w"> </span>map<span class="w"> </span>for<span class="w"> </span>sym:<span class="w"> </span>name,<span class="w"> </span>,<span class="m">0</span>,type,ignored&quot;<span class="w">  </span>according<span class="w"> </span>to<span class="w"> </span>Ultrix<span class="w"> </span>V4<span class="m">.0</span>.<span class="w"> </span>*/
__define_stab<span class="w"> </span>(N_NOMAP,<span class="w"> </span>0x34,<span class="w"> </span>&quot;NOMAP&quot;)

/*<span class="w"> </span>New<span class="w"> </span>stab<span class="w"> </span>from<span class="w"> </span>Solaris.<span class="w">  </span>I<span class="w"> </span>don&#39;t<span class="w"> </span>know<span class="w"> </span>what<span class="w"> </span>it<span class="w"> </span>means,<span class="w"> </span>but<span class="w"> </span>it
<span class="w">   </span>don&#39;t<span class="w"> </span>seem<span class="w"> </span>to<span class="w"> </span>contain<span class="w"> </span>useful<span class="w"> </span>information.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_OBJ,<span class="w"> </span>0x38,<span class="w"> </span>&quot;OBJ&quot;)

/*<span class="w"> </span>New<span class="w"> </span>stab<span class="w"> </span>from<span class="w"> </span>Solaris.<span class="w">  </span>I<span class="w"> </span>don&#39;t<span class="w"> </span>know<span class="w"> </span>what<span class="w"> </span>it<span class="w"> </span>means,<span class="w"> </span>but<span class="w"> </span>it
<span class="w">   </span>don&#39;t<span class="w"> </span>seem<span class="w"> </span>to<span class="w"> </span>contain<span class="w"> </span>useful<span class="w"> </span>information.<span class="w">  </span>Possibly<span class="w"> </span>related<span class="w"> </span>to<span class="w"> </span>the
<span class="w">   </span>optimization<span class="w"> </span>flags<span class="w"> </span>used<span class="w"> </span>in<span class="w"> </span>this<span class="w"> </span>module.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_OPT,<span class="w"> </span>0x3c,<span class="w"> </span>&quot;OPT&quot;)

/*<span class="w"> </span>Register<span class="w"> </span>variable.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>number<span class="w"> </span>of<span class="w"> </span>register.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_RSYM,<span class="w"> </span>0x40,<span class="w"> </span>&quot;RSYM&quot;)

/*<span class="w"> </span>Modula-<span class="m">2</span><span class="w"> </span>compilation<span class="w"> </span>unit.<span class="w">  </span>Can<span class="w"> </span>someone<span class="w"> </span>say<span class="w"> </span>what<span class="w"> </span>info<span class="w"> </span>it<span class="w"> </span>contains?<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_M2C,<span class="w"> </span>0x42,<span class="w"> </span>&quot;M2C&quot;)

/*<span class="w"> </span>Line<span class="w"> </span>number<span class="w"> </span>in<span class="w"> </span>text<span class="w"> </span>segment.<span class="w">  </span>Desc<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>line<span class="w"> </span>number;
<span class="w">   </span>value<span class="w"> </span>is<span class="w"> </span>corresponding<span class="w"> </span>address.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_SLINE,<span class="w"> </span>0x44,<span class="w"> </span>&quot;SLINE&quot;)

/*<span class="w"> </span>Similar,<span class="w"> </span>for<span class="w"> </span>data<span class="w"> </span>segment.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_DSLINE,<span class="w"> </span>0x46,<span class="w"> </span>&quot;DSLINE&quot;)

/*<span class="w"> </span>Similar,<span class="w"> </span>for<span class="w"> </span>bss<span class="w"> </span>segment.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_BSLINE,<span class="w"> </span>0x48,<span class="w"> </span>&quot;BSLINE&quot;)

/*<span class="w"> </span>Sun&#39;s<span class="w"> </span>source-code<span class="w"> </span>browser<span class="w"> </span>stabs.<span class="w">  </span>??<span class="w"> </span>Don&#39;t<span class="w"> </span>know<span class="w"> </span>what<span class="w"> </span>the<span class="w"> </span>fields<span class="w"> </span>are.
<span class="w">   </span>Supposedly<span class="w"> </span>the<span class="w"> </span>field<span class="w"> </span>is<span class="w"> </span>&quot;path<span class="w"> </span>to<span class="w"> </span>associated<span class="w"> </span>.cb<span class="w"> </span>file&quot;.<span class="w">  </span>THIS<span class="w"> </span>VALUE
<span class="w">   </span>OVERLAPS<span class="w"> </span>WITH<span class="w"> </span>N_BSLINE!<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_BROWS,<span class="w"> </span>0x48,<span class="w"> </span>&quot;BROWS&quot;)

/*<span class="w"> </span>GNU<span class="w"> </span>Modula-<span class="m">2</span><span class="w"> </span>definition<span class="w"> </span>module<span class="w"> </span>dependency.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>modification<span class="w"> </span>time
<span class="w">   </span>of<span class="w"> </span>the<span class="w"> </span>definition<span class="w"> </span>file.<span class="w">  </span>Other<span class="w"> </span>is<span class="w"> </span>non-zero<span class="w"> </span>if<span class="w"> </span>it<span class="w"> </span>is<span class="w"> </span>imported<span class="w"> </span>with<span class="w"> </span>the
<span class="w">   </span>GNU<span class="w"> </span>M2<span class="w"> </span>keyword<span class="w"> </span>%INITIALIZE.<span class="w">  </span>Perhaps<span class="w"> </span>N_M2C<span class="w"> </span>can<span class="w"> </span>be<span class="w"> </span>used<span class="w"> </span>if<span class="w"> </span>there
<span class="w">   </span>are<span class="w"> </span>enough<span class="w"> </span>empty<span class="w"> </span>fields?<span class="w"> </span>*/
__define_stab(N_DEFD,<span class="w"> </span>0x4a,<span class="w"> </span>&quot;DEFD&quot;)

/*<span class="w"> </span>THE<span class="w"> </span>FOLLOWING<span class="w"> </span>TWO<span class="w"> </span>STAB<span class="w"> </span>VALUES<span class="w"> </span>CONFLICT.<span class="w">  </span>Happily,<span class="w"> </span>one<span class="w"> </span>is<span class="w"> </span>for<span class="w"> </span>Modula-<span class="m">2</span>
<span class="w">   </span>and<span class="w"> </span>one<span class="w"> </span>is<span class="w"> </span>for<span class="w"> </span>C++.<span class="w">   </span>Still,...<span class="w"> </span>*/
/*<span class="w"> </span>GNU<span class="w"> </span>C++<span class="w"> </span>exception<span class="w"> </span>variable.<span class="w">  </span>Name<span class="w"> </span>is<span class="w"> </span>variable<span class="w"> </span>name.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_EHDECL,<span class="w"> </span>0x50,<span class="w"> </span>&quot;EHDECL&quot;)
/*<span class="w"> </span>Modula2<span class="w"> </span>info<span class="w"> </span>&quot;for<span class="w"> </span>imc&quot;:<span class="w">  </span>name,,<span class="m">0</span>,<span class="m">0</span>,<span class="m">0</span><span class="w">  </span>according<span class="w"> </span>to<span class="w"> </span>Ultrix<span class="w"> </span>V4<span class="m">.0</span>.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_MOD2,<span class="w"> </span>0x50,<span class="w"> </span>&quot;MOD2&quot;)

/*<span class="w"> </span>GNU<span class="w"> </span>C++<span class="w"> </span>`catch&#39;<span class="w"> </span>clause.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>its<span class="w"> </span>address.<span class="w">  </span>Desc<span class="w"> </span>is<span class="w"> </span>nonzero<span class="w"> </span>if
<span class="w">   </span>this<span class="w"> </span>entry<span class="w"> </span>is<span class="w"> </span>immediately<span class="w"> </span>followed<span class="w"> </span>by<span class="w"> </span>a<span class="w"> </span>CAUGHT<span class="w"> </span>stab<span class="w"> </span>saying<span class="w"> </span>what<span class="w"> </span>exception
<span class="w">   </span>was<span class="w"> </span>caught.<span class="w">  </span>Multiple<span class="w"> </span>CAUGHT<span class="w"> </span>stabs<span class="w"> </span>means<span class="w"> </span>that<span class="w"> </span>multiple<span class="w"> </span>exceptions
<span class="w">   </span>can<span class="w"> </span>be<span class="w"> </span>caught<span class="w"> </span>here.<span class="w">  </span>If<span class="w"> </span>Desc<span class="w"> </span>is<span class="w"> </span><span class="m">0</span>,<span class="w"> </span>it<span class="w"> </span>means<span class="w"> </span>all<span class="w"> </span>exceptions<span class="w"> </span>are<span class="w"> </span>caught
<span class="w">   </span>here.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_CATCH,<span class="w"> </span>0x54,<span class="w"> </span>&quot;CATCH&quot;)

/*<span class="w"> </span>Structure<span class="w"> </span>or<span class="w"> </span>union<span class="w"> </span>element.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>offset<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>structure.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_SSYM,<span class="w"> </span>0x60,<span class="w"> </span>&quot;SSYM&quot;)

/*<span class="w"> </span>Name<span class="w"> </span>of<span class="w"> </span>main<span class="w"> </span>source<span class="w"> </span>file.
<span class="w">   </span>Value<span class="w"> </span>is<span class="w"> </span>starting<span class="w"> </span>text<span class="w"> </span>address<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>compilation.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_SO,<span class="w"> </span>0x64,<span class="w"> </span>&quot;SO&quot;)

/*<span class="w"> </span>Automatic<span class="w"> </span>variable<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>stack.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>offset<span class="w"> </span>from<span class="w"> </span>frame<span class="w"> </span>pointer.
<span class="w">   </span>Also<span class="w"> </span>used<span class="w"> </span>for<span class="w"> </span>type<span class="w"> </span>descriptions.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_LSYM,<span class="w"> </span>0x80,<span class="w"> </span>&quot;LSYM&quot;)

/*<span class="w"> </span>Beginning<span class="w"> </span>of<span class="w"> </span>an<span class="w"> </span>include<span class="w"> </span>file.<span class="w">  </span>Only<span class="w"> </span>Sun<span class="w"> </span>uses<span class="w"> </span>this.
<span class="w">   </span>In<span class="w"> </span>an<span class="w"> </span>object<span class="w"> </span>file,<span class="w"> </span>only<span class="w"> </span>the<span class="w"> </span>name<span class="w"> </span>is<span class="w"> </span>significant.
<span class="w">   </span>The<span class="w"> </span>Sun<span class="w"> </span>linker<span class="w"> </span>puts<span class="w"> </span>data<span class="w"> </span>into<span class="w"> </span>some<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>other<span class="w"> </span>fields.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_BINCL,<span class="w"> </span>0x82,<span class="w"> </span>&quot;BINCL&quot;)

/*<span class="w"> </span>Name<span class="w"> </span>of<span class="w"> </span>sub-source<span class="w"> </span>file<span class="w"> </span>(<span class="c">#include file).</span>
<span class="w">   </span>Value<span class="w"> </span>is<span class="w"> </span>starting<span class="w"> </span>text<span class="w"> </span>address<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>compilation.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_SOL,<span class="w"> </span>0x84,<span class="w"> </span>&quot;SOL&quot;)

/*<span class="w"> </span>Parameter<span class="w"> </span>variable.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>offset<span class="w"> </span>from<span class="w"> </span>argument<span class="w"> </span>pointer.
<span class="w">   </span>(On<span class="w"> </span>most<span class="w"> </span>machines<span class="w"> </span>the<span class="w"> </span>argument<span class="w"> </span>pointer<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>same<span class="w"> </span>as<span class="w"> </span>the<span class="w"> </span>frame<span class="w"> </span>pointer.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_PSYM,<span class="w"> </span>0xa0,<span class="w"> </span>&quot;PSYM&quot;)

/*<span class="w"> </span>End<span class="w"> </span>of<span class="w"> </span>an<span class="w"> </span>include<span class="w"> </span>file.<span class="w">  </span>No<span class="w"> </span>name.
<span class="w">   </span>This<span class="w"> </span>and<span class="w"> </span>N_BINCL<span class="w"> </span>act<span class="w"> </span>as<span class="w"> </span>brackets<span class="w"> </span>around<span class="w"> </span>the<span class="w"> </span>file&#39;s<span class="w"> </span>output.
<span class="w">   </span>In<span class="w"> </span>an<span class="w"> </span>object<span class="w"> </span>file,<span class="w"> </span>there<span class="w"> </span>is<span class="w"> </span>no<span class="w"> </span>significant<span class="w"> </span>data<span class="w"> </span>in<span class="w"> </span>this<span class="w"> </span>entry.
<span class="w">   </span>The<span class="w"> </span>Sun<span class="w"> </span>linker<span class="w"> </span>puts<span class="w"> </span>data<span class="w"> </span>into<span class="w"> </span>some<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>fields.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_EINCL,<span class="w"> </span>0xa2,<span class="w"> </span>&quot;EINCL&quot;)

/*<span class="w"> </span>Alternate<span class="w"> </span>entry<span class="w"> </span>point.<span class="w">  </span>Value<span class="w"> </span>is<span class="w"> </span>its<span class="w"> </span>address.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_ENTRY,<span class="w"> </span>0xa4,<span class="w"> </span>&quot;ENTRY&quot;)

/*<span class="w"> </span>Beginning<span class="w"> </span>of<span class="w"> </span>lexical<span class="w"> </span>block.
<span class="w">   </span>The<span class="w"> </span>desc<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>nesting<span class="w"> </span>level<span class="w"> </span>in<span class="w"> </span>lexical<span class="w"> </span>blocks.
<span class="w">   </span>The<span class="w"> </span>value<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>address<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>start<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>text<span class="w"> </span>for<span class="w"> </span>the<span class="w"> </span>block.
<span class="w">   </span>The<span class="w"> </span>variables<span class="w"> </span>declared<span class="w"> </span>inside<span class="w"> </span>the<span class="w"> </span>block<span class="w"> </span>*precede*<span class="w"> </span>the<span class="w"> </span>N_LBRAC<span class="w"> </span>symbol.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_LBRAC,<span class="w"> </span>0xc0,<span class="w"> </span>&quot;LBRAC&quot;)

/*<span class="w"> </span>Place<span class="w"> </span>holder<span class="w"> </span>for<span class="w"> </span>deleted<span class="w"> </span>include<span class="w"> </span>file.<span class="w">  </span>Replaces<span class="w"> </span>a<span class="w"> </span>N_BINCL<span class="w"> </span>and<span class="w"> </span>everything
<span class="w">   </span>up<span class="w"> </span>to<span class="w"> </span>the<span class="w"> </span>corresponding<span class="w"> </span>N_EINCL.<span class="w">  </span>The<span class="w"> </span>Sun<span class="w"> </span>linker<span class="w"> </span>generates<span class="w"> </span>these<span class="w"> </span>when
<span class="w">   </span>it<span class="w"> </span>finds<span class="w"> </span>multiple<span class="w"> </span>identical<span class="w"> </span>copies<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>symbols<span class="w"> </span>from<span class="w"> </span>an<span class="w"> </span>include<span class="w"> </span>file.
<span class="w">   </span>This<span class="w"> </span>appears<span class="w"> </span>only<span class="w"> </span>in<span class="w"> </span>output<span class="w"> </span>from<span class="w"> </span>the<span class="w"> </span>Sun<span class="w"> </span>linker.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_EXCL,<span class="w"> </span>0xc2,<span class="w"> </span>&quot;EXCL&quot;)

/*<span class="w"> </span>Modula-<span class="m">2</span><span class="w"> </span>scope<span class="w"> </span>information.<span class="w">  </span>Can<span class="w"> </span>someone<span class="w"> </span>say<span class="w"> </span>what<span class="w"> </span>info<span class="w"> </span>it<span class="w"> </span>contains?<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_SCOPE,<span class="w"> </span>0xc4,<span class="w"> </span>&quot;SCOPE&quot;)

/*<span class="w"> </span>End<span class="w"> </span>of<span class="w"> </span>a<span class="w"> </span>lexical<span class="w"> </span>block.<span class="w">  </span>Desc<span class="w"> </span>matches<span class="w"> </span>the<span class="w"> </span>N_LBRAC&#39;s<span class="w"> </span>desc.
<span class="w">   </span>The<span class="w"> </span>value<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>address<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>end<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>text<span class="w"> </span>for<span class="w"> </span>the<span class="w"> </span>block.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_RBRAC,<span class="w"> </span>0xe0,<span class="w"> </span>&quot;RBRAC&quot;)

/*<span class="w"> </span>Begin<span class="w"> </span>named<span class="w"> </span>common<span class="w"> </span>block.<span class="w">  </span>Only<span class="w"> </span>the<span class="w"> </span>name<span class="w"> </span>is<span class="w"> </span>significant.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_BCOMM,<span class="w"> </span>0xe2,<span class="w"> </span>&quot;BCOMM&quot;)

/*<span class="w"> </span>End<span class="w"> </span>named<span class="w"> </span>common<span class="w"> </span>block.<span class="w">  </span>Only<span class="w"> </span>the<span class="w"> </span>name<span class="w"> </span>is<span class="w"> </span>significant
<span class="w">   </span>(and<span class="w"> </span>it<span class="w"> </span>should<span class="w"> </span>match<span class="w"> </span>the<span class="w"> </span>N_BCOMM).<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_ECOMM,<span class="w"> </span>0xe4,<span class="w"> </span>&quot;ECOMM&quot;)

/*<span class="w"> </span>End<span class="w"> </span>common<span class="w"> </span>(local<span class="w"> </span>name):<span class="w"> </span>value<span class="w"> </span>is<span class="w"> </span>address.
<span class="w">   </span>I&#39;m<span class="w"> </span>not<span class="w"> </span>sure<span class="w"> </span>how<span class="w"> </span>this<span class="w"> </span>is<span class="w"> </span>used.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_ECOML,<span class="w"> </span>0xe8,<span class="w"> </span>&quot;ECOML&quot;)

/*<span class="w"> </span>These<span class="w"> </span>STAB&#39;s<span class="w"> </span>are<span class="w"> </span>used<span class="w"> </span>on<span class="w"> </span>Gould<span class="w"> </span>systems<span class="w"> </span>for<span class="w"> </span>Non-Base<span class="w"> </span>register<span class="w"> </span>symbols
<span class="w">   </span>or<span class="w"> </span>something<span class="w"> </span>like<span class="w"> </span>that.<span class="w">  </span>FIXME.<span class="w">  </span>I<span class="w"> </span>have<span class="w"> </span>assigned<span class="w"> </span>the<span class="w"> </span>values<span class="w"> </span>at<span class="w"> </span>random
<span class="w">   </span>since<span class="w"> </span>I<span class="w"> </span>don&#39;t<span class="w"> </span>have<span class="w"> </span>a<span class="w"> </span>Gould<span class="w"> </span>here.<span class="w">  </span>Fixups<span class="w"> </span>from<span class="w"> </span>Gould<span class="w"> </span>folk<span class="w"> </span>welcome...<span class="w"> </span>*/
__define_stab<span class="w"> </span>(N_NBTEXT,<span class="w"> </span>0xF0,<span class="w"> </span>&quot;NBTEXT&quot;)
__define_stab<span class="w"> </span>(N_NBDATA,<span class="w"> </span>0xF2,<span class="w"> </span>&quot;NBDATA&quot;)
__define_stab<span class="w"> </span>(N_NBBSS,<span class="w">  </span>0xF4,<span class="w"> </span>&quot;NBBSS&quot;)
__define_stab<span class="w"> </span>(N_NBSTS,<span class="w">  </span>0xF6,<span class="w"> </span>&quot;NBSTS&quot;)
__define_stab<span class="w"> </span>(N_NBLCS,<span class="w">  </span>0xF8,<span class="w"> </span>&quot;NBLCS&quot;)

/*<span class="w"> </span>Second<span class="w"> </span>symbol<span class="w"> </span>entry<span class="w"> </span>containing<span class="w"> </span>a<span class="w"> </span>length-value<span class="w"> </span>for<span class="w"> </span>the<span class="w"> </span>preceding<span class="w"> </span>entry.
<span class="w">   </span>The<span class="w"> </span>value<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>length.<span class="w">  </span>*/
__define_stab<span class="w"> </span>(N_LENG,<span class="w"> </span>0xfe,<span class="w"> </span>&quot;LENG&quot;)

/*<span class="w"> </span>The<span class="w"> </span>above<span class="w"> </span>information,<span class="w"> </span>in<span class="w"> </span>matrix<span class="w"> </span>format.

<span class="w">			</span>STAB<span class="w"> </span>MATRIX
<span class="w">	</span>_________________________________________________
<span class="w">	</span>|<span class="w"> </span><span class="m">00</span><span class="w"> </span>-<span class="w"> </span>1F<span class="w"> </span>are<span class="w"> </span>not<span class="w"> </span>dbx<span class="w"> </span>stab<span class="w"> </span>symbols<span class="w">		</span>|
<span class="w">	</span>|<span class="w"> </span>In<span class="w"> </span>most<span class="w"> </span>cases,<span class="w"> </span>the<span class="w"> </span>low<span class="w"> </span>bit<span class="w"> </span>is<span class="w"> </span>the<span class="w"> </span>EXTernal<span class="w"> </span>bit|

<span class="w">	</span>|<span class="w"> </span><span class="m">00</span><span class="w"> </span>UNDEF<span class="w">  </span>|<span class="w"> </span><span class="m">02</span><span class="w"> </span>ABS<span class="w">	</span>|<span class="w"> </span><span class="m">04</span><span class="w"> </span>TEXT<span class="w">   </span>|<span class="w"> </span><span class="m">06</span><span class="w"> </span>DATA<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">01</span><span class="w">  </span>|EXT<span class="w">  </span>|<span class="w"> </span><span class="m">03</span><span class="w">  </span>|EXT<span class="w">	</span>|<span class="w"> </span><span class="m">05</span><span class="w">  </span>|EXT<span class="w">  </span>|<span class="w"> </span><span class="m">07</span><span class="w">  </span>|EXT<span class="w">	</span>|

<span class="w">	</span>|<span class="w"> </span><span class="m">08</span><span class="w"> </span>BSS<span class="w">    </span>|<span class="w"> </span>0A<span class="w"> </span>INDR<span class="w">	</span>|<span class="w"> </span>0C<span class="w"> </span>FN_SEQ<span class="w"> </span>|<span class="w"> </span>0E<span class="w">   	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">09</span><span class="w">  </span>|EXT<span class="w">  </span>|<span class="w"> </span>0B<span class="w"> 	</span>|<span class="w"> </span>0D<span class="w">	    </span>|<span class="w"> </span>0F<span class="w">	</span>|

<span class="w">	</span>|<span class="w"> </span><span class="m">10</span><span class="w"> 	    </span>|<span class="w"> </span><span class="m">12</span><span class="w"> </span>COMM<span class="w">	</span>|<span class="w"> </span><span class="m">14</span><span class="w"> </span>SETA<span class="w">   </span>|<span class="w"> </span><span class="m">16</span><span class="w"> </span>SETT<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">11</span><span class="w">	    </span>|<span class="w"> </span><span class="m">13</span><span class="w">	</span>|<span class="w"> </span><span class="m">15</span><span class="w"> 	    </span>|<span class="w"> </span><span class="m">17</span><span class="w">	</span>|

<span class="w">	</span>|<span class="w"> </span><span class="m">18</span><span class="w"> </span>SETD<span class="w">   </span>|<span class="w"> </span>1A<span class="w"> </span>SETB<span class="w">	</span>|<span class="w"> </span>1C<span class="w"> </span>SETV<span class="w">   </span>|<span class="w"> </span>1E<span class="w"> </span>WARNING|
<span class="w">	</span>|<span class="w"> </span><span class="m">19</span><span class="w">	    </span>|<span class="w"> </span>1B<span class="w">	</span>|<span class="w"> </span>1D<span class="w"> 	    </span>|<span class="w"> </span>1F<span class="w"> </span>FN<span class="w">	</span>|

<span class="w">	</span>|_______________________________________________|
<span class="w">	</span>|<span class="w"> </span>Debug<span class="w"> </span>entries<span class="w"> </span>with<span class="w"> </span>bit<span class="w"> </span><span class="m">01</span><span class="w"> </span>set<span class="w"> </span>are<span class="w"> </span>unused.<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">20</span><span class="w"> </span>GSYM<span class="w">   </span>|<span class="w"> </span><span class="m">22</span><span class="w"> </span>FNAME<span class="w">	</span>|<span class="w"> </span><span class="m">24</span><span class="w"> </span>FUN<span class="w">    </span>|<span class="w"> </span><span class="m">26</span><span class="w"> </span>STSYM<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">28</span><span class="w"> </span>LCSYM<span class="w">  </span>|<span class="w"> </span>2A<span class="w"> </span>MAIN<span class="w">	</span>|<span class="w"> </span>2C<span class="w">	    </span>|<span class="w"> </span>2E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">30</span><span class="w"> </span>PC<span class="w">	    </span>|<span class="w"> </span><span class="m">32</span><span class="w"> </span>NSYMS<span class="w">	</span>|<span class="w"> </span><span class="m">34</span><span class="w"> </span>NOMAP<span class="w">  </span>|<span class="w"> </span><span class="m">36</span><span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">38</span><span class="w"> </span>OBJ<span class="w">    </span>|<span class="w"> </span>3A<span class="w">	</span>|<span class="w"> </span>3C<span class="w"> </span>OPT<span class="w">    </span>|<span class="w"> </span>3E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">40</span><span class="w"> </span>RSYM<span class="w">   </span>|<span class="w"> </span><span class="m">42</span><span class="w"> </span>M2C<span class="w">	</span>|<span class="w"> </span><span class="m">44</span><span class="w"> </span>SLINE<span class="w">  </span>|<span class="w"> </span><span class="m">46</span><span class="w"> </span>DSLINE<span class="w"> </span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">48</span><span class="w"> </span>BSLINE*|<span class="w"> </span>4A<span class="w"> </span>DEFD<span class="w">	</span>|<span class="w"> </span>4C<span class="w">        </span>|<span class="w"> </span>4E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">50</span><span class="w"> </span>EHDECL*|<span class="w"> </span><span class="m">52</span><span class="w">	</span>|<span class="w"> </span><span class="m">54</span><span class="w"> </span>CATCH<span class="w">  </span>|<span class="w"> </span><span class="m">56</span><span class="w">        </span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">58</span><span class="w">        </span>|<span class="w"> </span>5A<span class="w">        </span>|<span class="w"> </span>5C<span class="w">        </span>|<span class="w"> </span>5E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">60</span><span class="w"> </span>SSYM<span class="w">   </span>|<span class="w"> </span><span class="m">62</span><span class="w">	</span>|<span class="w"> </span><span class="m">64</span><span class="w"> </span>SO<span class="w">	    </span>|<span class="w"> </span><span class="m">66</span><span class="w"> 	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">68</span><span class="w"> 	    </span>|<span class="w"> </span>6A<span class="w">	</span>|<span class="w"> </span>6C<span class="w">	    </span>|<span class="w"> </span>6E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">70</span><span class="w">	    </span>|<span class="w"> </span><span class="m">72</span><span class="w">	</span>|<span class="w"> </span><span class="m">74</span><span class="w">	    </span>|<span class="w"> </span><span class="m">76</span><span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">78</span><span class="w">	    </span>|<span class="w"> </span>7A<span class="w">	</span>|<span class="w"> </span>7C<span class="w">	    </span>|<span class="w"> </span>7E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">80</span><span class="w"> </span>LSYM<span class="w">   </span>|<span class="w"> </span><span class="m">82</span><span class="w"> </span>BINCL<span class="w">	</span>|<span class="w"> </span><span class="m">84</span><span class="w"> </span>SOL<span class="w">    </span>|<span class="w"> </span><span class="m">86</span><span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">88</span><span class="w">	    </span>|<span class="w"> </span>8A<span class="w">	</span>|<span class="w"> </span>8C<span class="w">	    </span>|<span class="w"> </span>8E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">90</span><span class="w">	    </span>|<span class="w"> </span><span class="m">92</span><span class="w">	</span>|<span class="w"> </span><span class="m">94</span><span class="w">	    </span>|<span class="w"> </span><span class="m">96</span><span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span><span class="m">98</span><span class="w">	    </span>|<span class="w"> </span>9A<span class="w">	</span>|<span class="w"> </span>9C<span class="w">	    </span>|<span class="w"> </span>9E<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>A0<span class="w"> </span>PSYM<span class="w">   </span>|<span class="w"> </span>A2<span class="w"> </span>EINCL<span class="w">	</span>|<span class="w"> </span>A4<span class="w"> </span>ENTRY<span class="w">  </span>|<span class="w"> </span>A6<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>A8<span class="w">	    </span>|<span class="w"> </span>AA<span class="w">	</span>|<span class="w"> </span>AC<span class="w">	    </span>|<span class="w"> </span>AE<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>B0<span class="w">	    </span>|<span class="w"> </span>B2<span class="w">	</span>|<span class="w"> </span>B4<span class="w">	    </span>|<span class="w"> </span>B6<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>B8<span class="w">	    </span>|<span class="w"> </span>BA<span class="w">	</span>|<span class="w"> </span>BC<span class="w">	    </span>|<span class="w"> </span>BE<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>C0<span class="w"> </span>LBRAC<span class="w">  </span>|<span class="w"> </span>C2<span class="w"> </span>EXCL<span class="w">	</span>|<span class="w"> </span>C4<span class="w"> </span>SCOPE<span class="w">  </span>|<span class="w"> </span>C6<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>C8<span class="w">	    </span>|<span class="w"> </span>CA<span class="w">	</span>|<span class="w"> </span>CC<span class="w">	    </span>|<span class="w"> </span>CE<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>D0<span class="w">	    </span>|<span class="w"> </span>D2<span class="w">	</span>|<span class="w"> </span>D4<span class="w">	    </span>|<span class="w"> </span>D6<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>D8<span class="w">	    </span>|<span class="w"> </span>DA<span class="w">	</span>|<span class="w"> </span>DC<span class="w">	    </span>|<span class="w"> </span>DE<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>E0<span class="w"> </span>RBRAC<span class="w">  </span>|<span class="w"> </span>E2<span class="w"> </span>BCOMM<span class="w">	</span>|<span class="w"> </span>E4<span class="w"> </span>ECOMM<span class="w">  </span>|<span class="w"> </span>E6<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>E8<span class="w"> </span>ECOML<span class="w">  </span>|<span class="w"> </span>EA<span class="w">	</span>|<span class="w"> </span>EC<span class="w">	    </span>|<span class="w"> </span>EE<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>F0<span class="w">	    </span>|<span class="w"> </span>F2<span class="w">	</span>|<span class="w"> </span>F4<span class="w">	    </span>|<span class="w"> </span>F6<span class="w">	</span>|
<span class="w">	</span>|<span class="w"> </span>F8<span class="w">	    </span>|<span class="w"> </span>FA<span class="w">	</span>|<span class="w"> </span>FC<span class="w">	    </span>|<span class="w"> </span>FE<span class="w"> </span>LENG<span class="w">	</span>|
<span class="w">	</span>+-----------------------------------------------+
<span class="w"> </span>*<span class="w"> </span><span class="m">50</span><span class="w"> </span>EHDECL<span class="w"> </span>is<span class="w"> </span>also<span class="w"> </span>MOD2.
<span class="w"> </span>*<span class="w"> </span><span class="m">48</span><span class="w"> </span>BSLINE<span class="w"> </span>is<span class="w"> </span>also<span class="w"> </span>BROWS.
<span class="w"> </span>*/
</pre></div>
</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.causal.agency/cgit-pink/about/'>cgit-pink 1.4.1-2-gfad0</a> (<a href='https://git-scm.com/'>git 2.36.2.497.gbbea4dcf42</a>) at 2025-05-31 02:48:12 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>

<span class='ctx'>     autocomplete_free(commands_ac);</span>
<span class='ctx'>     autocomplete_free(who_ac);</span>
<span class='hunk'>@@ -1398,2353 +1311,6 @@ _cmd_complete_parameters(char *input, int *size)</span>
<span class='ctx'>     return;</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-// The command functions</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_connect(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean result = FALSE;</span>
<span class='del'>-</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if ((conn_status != JABBER_DISCONNECTED) &amp;&amp; (conn_status != JABBER_STARTED)) {</span>
<span class='del'>-        cons_show("You are either connected already, or a login is in process.");</span>
<span class='del'>-        result = TRUE;</span>
<span class='del'>-    } else {</span>
<span class='del'>-        char *user = args[0];</span>
<span class='del'>-        char *altdomain = args[1];</span>
<span class='del'>-        char *lower = g_utf8_strdown(user, -1);</span>
<span class='del'>-        char *jid;</span>
<span class='del'>-</span>
<span class='del'>-        ProfAccount *account = accounts_get_account(lower);</span>
<span class='del'>-        if (account != NULL) {</span>
<span class='del'>-            if (account-&gt;resource != NULL) {</span>
<span class='del'>-                jid = create_fulljid(account-&gt;jid, account-&gt;resource);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                jid = strdup(account-&gt;jid);</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            if (account-&gt;password == NULL) {</span>
<span class='del'>-                account-&gt;password = _ask_password();</span>
<span class='del'>-            }</span>
<span class='del'>-            cons_show("Connecting with account %s as %s", account-&gt;name, jid);</span>
<span class='del'>-            conn_status = jabber_connect_with_account(account);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            char *passwd = _ask_password();</span>
<span class='del'>-            jid = strdup(lower);</span>
<span class='del'>-            cons_show("Connecting as %s", jid);</span>
<span class='del'>-            conn_status = jabber_connect_with_details(jid, passwd, altdomain);</span>
<span class='del'>-            free(passwd);</span>
<span class='del'>-        }</span>
<span class='del'>-        g_free(lower);</span>
<span class='del'>-</span>
<span class='del'>-        if (conn_status == JABBER_DISCONNECTED) {</span>
<span class='del'>-            cons_show_error("Connection attempt for %s failed.", jid);</span>
<span class='del'>-            log_debug("Connection attempt for %s failed", jid);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        accounts_free_account(account);</span>
<span class='del'>-        free(jid);</span>
<span class='del'>-</span>
<span class='del'>-        result = TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_account(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *command = args[0];</span>
<span class='del'>-</span>
<span class='del'>-    if (command == NULL) {</span>
<span class='del'>-        if (jabber_get_connection_status() != JABBER_CONNECTED) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='del'>-            cons_show_account(account);</span>
<span class='del'>-            accounts_free_account(account);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "list") == 0) {</span>
<span class='del'>-        gchar **accounts = accounts_get_list();</span>
<span class='del'>-        cons_show_account_list(accounts);</span>
<span class='del'>-        g_strfreev(accounts);</span>
<span class='del'>-    } else if (strcmp(command, "show") == 0) {</span>
<span class='del'>-        char *account_name = args[1];</span>
<span class='del'>-        if (account_name == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            ProfAccount *account = accounts_get_account(account_name);</span>
<span class='del'>-            if (account == NULL) {</span>
<span class='del'>-                cons_show("No such account.");</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show_account(account);</span>
<span class='del'>-                accounts_free_account(account);</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "add") == 0) {</span>
<span class='del'>-        char *account_name = args[1];</span>
<span class='del'>-        if (account_name == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            accounts_add(account_name, NULL);</span>
<span class='del'>-            cons_show("Account created.");</span>
<span class='del'>-            cons_show("");</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "enable") == 0) {</span>
<span class='del'>-        char *account_name = args[1];</span>
<span class='del'>-        if (account_name == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            if (accounts_enable(account_name)) {</span>
<span class='del'>-                cons_show("Account enabled.");</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("No such account: %s", account_name);</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "disable") == 0) {</span>
<span class='del'>-        char *account_name = args[1];</span>
<span class='del'>-        if (account_name == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            if (accounts_disable(account_name)) {</span>
<span class='del'>-                cons_show("Account disabled.");</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("No such account: %s", account_name);</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "rename") == 0) {</span>
<span class='del'>-        if (g_strv_length(args) != 3) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            char *account_name = args[1];</span>
<span class='del'>-            char *new_name = args[2];</span>
<span class='del'>-</span>
<span class='del'>-            if (accounts_rename(account_name, new_name)) {</span>
<span class='del'>-                cons_show("Account renamed.");</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("Either account %s doesn't exist, or account %s already exists.", account_name, new_name);</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "set") == 0) {</span>
<span class='del'>-        if (g_strv_length(args) != 4) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            char *account_name = args[1];</span>
<span class='del'>-            char *property = args[2];</span>
<span class='del'>-            char *value = args[3];</span>
<span class='del'>-</span>
<span class='del'>-            if (!accounts_account_exists(account_name)) {</span>
<span class='del'>-                cons_show("Account %s doesn't exist", account_name);</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                if (strcmp(property, "jid") == 0) {</span>
<span class='del'>-                    Jid *jid = jid_create(args[3]);</span>
<span class='del'>-                    if (jid == NULL) {</span>
<span class='del'>-                        cons_show("Malformed jid: %s", value);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        accounts_set_jid(account_name, jid-&gt;barejid);</span>
<span class='del'>-                        cons_show("Updated jid for account %s: %s", account_name, jid-&gt;barejid);</span>
<span class='del'>-                        if (jid-&gt;resourcepart != NULL) {</span>
<span class='del'>-                            accounts_set_resource(account_name, jid-&gt;resourcepart);</span>
<span class='del'>-                            cons_show("Updated resource for account %s: %s", account_name, jid-&gt;resourcepart);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        cons_show("");</span>
<span class='del'>-                    }</span>
<span class='del'>-                    jid_destroy(jid);</span>
<span class='del'>-                } else if (strcmp(property, "server") == 0) {</span>
<span class='del'>-                    accounts_set_server(account_name, value);</span>
<span class='del'>-                    cons_show("Updated server for account %s: %s", account_name, value);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else if (strcmp(property, "resource") == 0) {</span>
<span class='del'>-                    accounts_set_resource(account_name, value);</span>
<span class='del'>-                    cons_show("Updated resource for account %s: %s", account_name, value);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else if (strcmp(property, "password") == 0) {</span>
<span class='del'>-                    accounts_set_password(account_name, value);</span>
<span class='del'>-                    cons_show("Updated password for account %s", account_name);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else if (strcmp(property, "muc") == 0) {</span>
<span class='del'>-                    accounts_set_muc_service(account_name, value);</span>
<span class='del'>-                    cons_show("Updated muc service for account %s: %s", account_name, value);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else if (strcmp(property, "nick") == 0) {</span>
<span class='del'>-                    accounts_set_muc_nick(account_name, value);</span>
<span class='del'>-                    cons_show("Updated muc nick for account %s: %s", account_name, value);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else if (strcmp(property, "status") == 0) {</span>
<span class='del'>-                    if (!valid_resource_presence_string(value) &amp;&amp; (strcmp(value, "last") != 0)) {</span>
<span class='del'>-                        cons_show("Invalid status: %s", value);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        accounts_set_login_presence(account_name, value);</span>
<span class='del'>-                        cons_show("Updated login status for account %s: %s", account_name, value);</span>
<span class='del'>-                    }</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else if (valid_resource_presence_string(property)) {</span>
<span class='del'>-                        int intval;</span>
<span class='del'>-</span>
<span class='del'>-                        if (_strtoi(value, &amp;intval, -128, 127) == 0) {</span>
<span class='del'>-                            resource_presence_t presence_type = resource_presence_from_string(property);</span>
<span class='del'>-                            switch (presence_type)</span>
<span class='del'>-                            {</span>
<span class='del'>-                                case (RESOURCE_ONLINE):</span>
<span class='del'>-                                    accounts_set_priority_online(account_name, intval);</span>
<span class='del'>-                                    break;</span>
<span class='del'>-                                case (RESOURCE_CHAT):</span>
<span class='del'>-                                    accounts_set_priority_chat(account_name, intval);</span>
<span class='del'>-                                    break;</span>
<span class='del'>-                                case (RESOURCE_AWAY):</span>
<span class='del'>-                                    accounts_set_priority_away(account_name, intval);</span>
<span class='del'>-                                    break;</span>
<span class='del'>-                                case (RESOURCE_XA):</span>
<span class='del'>-                                    accounts_set_priority_xa(account_name, intval);</span>
<span class='del'>-                                    break;</span>
<span class='del'>-                                case (RESOURCE_DND):</span>
<span class='del'>-                                    accounts_set_priority_dnd(account_name, intval);</span>
<span class='del'>-                                    break;</span>
<span class='del'>-                            }</span>
<span class='del'>-                            jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-                            resource_presence_t last_presence = accounts_get_last_presence(jabber_get_account_name());</span>
<span class='del'>-                            if (conn_status == JABBER_CONNECTED &amp;&amp; presence_type == last_presence) {</span>
<span class='del'>-                                presence_update(last_presence, jabber_get_presence_message(), 0);</span>
<span class='del'>-                            }</span>
<span class='del'>-                            cons_show("Updated %s priority for account %s: %s", property, account_name, value);</span>
<span class='del'>-                            cons_show("");</span>
<span class='del'>-                        }</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("Invalid property: %s", property);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(command, "clear") == 0) {</span>
<span class='del'>-        if (g_strv_length(args) != 3) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            char *account_name = args[1];</span>
<span class='del'>-            char *property = args[2];</span>
<span class='del'>-</span>
<span class='del'>-            if (!accounts_account_exists(account_name)) {</span>
<span class='del'>-                cons_show("Account %s doesn't exist", account_name);</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                if (strcmp(property, "password") == 0) {</span>
<span class='del'>-                    accounts_clear_password(account_name);</span>
<span class='del'>-                    cons_show("Removed password for account %s", account_name);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("Invalid property: %s", property);</span>
<span class='del'>-                    cons_show("");</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_sub(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are currently not connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    char *subcmd, *jid;</span>
<span class='del'>-    subcmd = args[0];</span>
<span class='del'>-    jid = args[1];</span>
<span class='del'>-</span>
<span class='del'>-    if (subcmd == NULL) {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(subcmd, "sent") == 0) {</span>
<span class='del'>-        cons_show_sent_subs();</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(subcmd, "received") == 0) {</span>
<span class='del'>-        cons_show_received_subs();</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if ((win_type != WIN_CHAT) &amp;&amp; (jid == NULL)) {</span>
<span class='del'>-        cons_show("You must specify a contact.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (jid == NULL) {</span>
<span class='del'>-        jid = ui_current_recipient();</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    Jid *jidp = jid_create(jid);</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(subcmd, "allow") == 0) {</span>
<span class='del'>-        presence_subscription(jidp-&gt;barejid, PRESENCE_SUBSCRIBED);</span>
<span class='del'>-        cons_show("Accepted subscription for %s", jidp-&gt;barejid);</span>
<span class='del'>-        log_info("Accepted subscription for %s", jidp-&gt;barejid);</span>
<span class='del'>-    } else if (strcmp(subcmd, "deny") == 0) {</span>
<span class='del'>-        presence_subscription(jidp-&gt;barejid, PRESENCE_UNSUBSCRIBED);</span>
<span class='del'>-        cons_show("Deleted/denied subscription for %s", jidp-&gt;barejid);</span>
<span class='del'>-        log_info("Deleted/denied subscription for %s", jidp-&gt;barejid);</span>
<span class='del'>-    } else if (strcmp(subcmd, "request") == 0) {</span>
<span class='del'>-        presence_subscription(jidp-&gt;barejid, PRESENCE_SUBSCRIBE);</span>
<span class='del'>-        cons_show("Sent subscription request to %s.", jidp-&gt;barejid);</span>
<span class='del'>-        log_info("Sent subscription request to %s.", jidp-&gt;barejid);</span>
<span class='del'>-    } else if (strcmp(subcmd, "show") == 0) {</span>
<span class='del'>-        PContact contact = roster_get_contact(jidp-&gt;barejid);</span>
<span class='del'>-        if ((contact == NULL) || (p_contact_subscription(contact) == NULL)) {</span>
<span class='del'>-            if (win_type == WIN_CHAT) {</span>
<span class='del'>-                ui_current_print_line("No subscription information for %s.", jidp-&gt;barejid);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("No subscription information for %s.", jidp-&gt;barejid);</span>
<span class='del'>-            }</span>
<span class='del'>-        } else {</span>
<span class='del'>-            if (win_type == WIN_CHAT) {</span>
<span class='del'>-                if (p_contact_pending_out(contact)) {</span>
<span class='del'>-                    ui_current_print_line("%s subscription status: %s, request pending.",</span>
<span class='del'>-                        jidp-&gt;barejid, p_contact_subscription(contact));</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    ui_current_print_line("%s subscription status: %s.", jidp-&gt;barejid,</span>
<span class='del'>-                        p_contact_subscription(contact));</span>
<span class='del'>-                }</span>
<span class='del'>-            } else {</span>
<span class='del'>-                if (p_contact_pending_out(contact)) {</span>
<span class='del'>-                    cons_show("%s subscription status: %s, request pending.",</span>
<span class='del'>-                        jidp-&gt;barejid, p_contact_subscription(contact));</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("%s subscription status: %s.", jidp-&gt;barejid,</span>
<span class='del'>-                        p_contact_subscription(contact));</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    jid_destroy(jidp);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_disconnect(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    if (jabber_get_connection_status() == JABBER_CONNECTED) {</span>
<span class='del'>-        char *jid = strdup(jabber_get_fulljid());</span>
<span class='del'>-        prof_handle_disconnect(jid);</span>
<span class='del'>-        free(jid);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_quit(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    log_info("Profanity is shutting down...");</span>
<span class='del'>-    exit(0);</span>
<span class='del'>-    return FALSE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_wins(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    if (args[0] == NULL) {</span>
<span class='del'>-        cons_show_wins();</span>
<span class='del'>-    } else if (strcmp(args[0], "tidy") == 0) {</span>
<span class='del'>-        ui_tidy_wins();</span>
<span class='del'>-    } else if (strcmp(args[0], "prune") == 0) {</span>
<span class='del'>-        ui_prune_wins();</span>
<span class='del'>-    }</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_win(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    int num = atoi(args[0]);</span>
<span class='del'>-    if (ui_win_exists(num)) {</span>
<span class='del'>-        ui_switch_win(num);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Window %d does not exist.", num);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static</span>
<span class='del'>-gint _compare_commands(Command *a, Command *b)</span>
<span class='del'>-{</span>
<span class='del'>-    const char * utf8_str_a = a-&gt;cmd;</span>
<span class='del'>-    const char * utf8_str_b = b-&gt;cmd;</span>
<span class='del'>-</span>
<span class='del'>-    gchar *key_a = g_utf8_collate_key(utf8_str_a, -1);</span>
<span class='del'>-    gchar *key_b = g_utf8_collate_key(utf8_str_b, -1);</span>
<span class='del'>-</span>
<span class='del'>-    gint result = g_strcmp0(key_a, key_b);</span>
<span class='del'>-</span>
<span class='del'>-    g_free(key_a);</span>
<span class='del'>-    g_free(key_b);</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static void</span>
<span class='del'>-_cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size)</span>
<span class='del'>-{</span>
<span class='del'>-    cons_show("");</span>
<span class='del'>-    cons_show("%s", heading);</span>
<span class='del'>-    cons_show("");</span>
<span class='del'>-</span>
<span class='del'>-    GList *ordered_commands = NULL;</span>
<span class='del'>-    int i;</span>
<span class='del'>-    for (i = 0; i &lt; filter_size; i++) {</span>
<span class='del'>-        Command *cmd = g_hash_table_lookup(commands, cmd_filter[i]);</span>
<span class='del'>-        ordered_commands = g_list_insert_sorted(ordered_commands, cmd, (GCompareFunc)_compare_commands);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    GList *curr = ordered_commands;</span>
<span class='del'>-    while (curr != NULL) {</span>
<span class='del'>-        Command *cmd = curr-&gt;data;</span>
<span class='del'>-        cons_show("%-12s: %s", cmd-&gt;cmd, cmd-&gt;help.short_help);</span>
<span class='del'>-        curr = g_list_next(curr);</span>
<span class='del'>-    }</span>
<span class='del'>-    g_list_free(ordered_commands);</span>
<span class='del'>-    g_list_free(curr);</span>
<span class='del'>-</span>
<span class='del'>-    cons_show("");</span>
<span class='del'>-    cons_show("Use /help [command] without the leading slash, for help on a specific command");</span>
<span class='del'>-    cons_show("");</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_help(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    int num_args = g_strv_length(args);</span>
<span class='del'>-    if (num_args == 0) {</span>
<span class='del'>-        cons_help();</span>
<span class='del'>-    } else if (strcmp(args[0], "commands") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show("All commands");</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-</span>
<span class='del'>-        GList *ordered_commands = NULL;</span>
<span class='del'>-        GHashTableIter iter;</span>
<span class='del'>-        gpointer key;</span>
<span class='del'>-        gpointer value;</span>
<span class='del'>-</span>
<span class='del'>-        g_hash_table_iter_init(&amp;iter, commands);</span>
<span class='del'>-        while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='del'>-            ordered_commands = g_list_insert_sorted(ordered_commands, value, (GCompareFunc)_compare_commands);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        GList *curr = ordered_commands;</span>
<span class='del'>-        while (curr != NULL) {</span>
<span class='del'>-            Command *cmd = curr-&gt;data;</span>
<span class='del'>-            cons_show("%-12s: %s", cmd-&gt;cmd, cmd-&gt;help.short_help);</span>
<span class='del'>-            curr = g_list_next(curr);</span>
<span class='del'>-        }</span>
<span class='del'>-        g_list_free(ordered_commands);</span>
<span class='del'>-        g_list_free(curr);</span>
<span class='del'>-</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show("Use /help [command] without the leading slash, for help on a specific command");</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "basic") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/about", "/clear", "/close", "/connect",</span>
<span class='del'>-            "/disconnect", "/help", "/msg", "/join", "/quit", "/vercheck",</span>
<span class='del'>-            "/wins" };</span>
<span class='del'>-        _cmd_show_filtered_help("Basic commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "chatting") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/chlog", "/duck", "/gone", "/history",</span>
<span class='del'>-            "/info", "/intype", "/msg", "/notify", "/outtype", "/status",</span>
<span class='del'>-            "/close", "/clear", "/tiny" };</span>
<span class='del'>-        _cmd_show_filtered_help("Chat commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "groupchat") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/close", "/clear", "/decline", "/grlog",</span>
<span class='del'>-            "/invite", "/invites", "/join", "/leave", "/notify", "/msg",</span>
<span class='del'>-            "/rooms", "/tiny", "/who", "/nick" };</span>
<span class='del'>-        _cmd_show_filtered_help("Groupchat commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "presence") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/autoaway", "/away", "/chat", "/dnd",</span>
<span class='del'>-            "/online", "/priority", "/account", "/status", "/statuses", "/who",</span>
<span class='del'>-            "/xa" };</span>
<span class='del'>-        _cmd_show_filtered_help("Presence commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "contacts") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/group", "/roster", "/sub", "/who" };</span>
<span class='del'>-        _cmd_show_filtered_help("Roster commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "service") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/caps", "/disco", "/info", "/software", "/rooms" };</span>
<span class='del'>-        _cmd_show_filtered_help("Service discovery commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "settings") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/account", "/autoaway", "/autoping", "/autoconnect", "/beep",</span>
<span class='del'>-            "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype",</span>
<span class='del'>-            "/log", "/mouse", "/notify", "/outtype", "/prefs", "/priority",</span>
<span class='del'>-            "/reconnect", "/roster", "/splash", "/states", "/statuses", "/theme",</span>
<span class='del'>-            "/titlebar", "/vercheck" };</span>
<span class='del'>-        _cmd_show_filtered_help("Settings commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "other") == 0) {</span>
<span class='del'>-        gchar *filter[] = { "/duck", "/vercheck" };</span>
<span class='del'>-        _cmd_show_filtered_help("Other commands", filter, ARRAY_SIZE(filter));</span>
<span class='del'>-</span>
<span class='del'>-    } else if (strcmp(args[0], "navigation") == 0) {</span>
<span class='del'>-        cons_navigation_help();</span>
<span class='del'>-    } else {</span>
<span class='del'>-        char *cmd = args[0];</span>
<span class='del'>-        char cmd_with_slash[1 + strlen(cmd) + 1];</span>
<span class='del'>-        sprintf(cmd_with_slash, "/%s", cmd);</span>
<span class='del'>-</span>
<span class='del'>-        const gchar **help_text = NULL;</span>
<span class='del'>-        Command *command = g_hash_table_lookup(commands, cmd_with_slash);</span>
<span class='del'>-</span>
<span class='del'>-        if (command != NULL) {</span>
<span class='del'>-            help_text = command-&gt;help.long_help;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-</span>
<span class='del'>-        if (help_text != NULL) {</span>
<span class='del'>-            int i;</span>
<span class='del'>-            for (i = 0; help_text[i] != NULL; i++) {</span>
<span class='del'>-                cons_show(help_text[i]);</span>
<span class='del'>-            }</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("No such command.");</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_about(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    cons_show("");</span>
<span class='del'>-    cons_about();</span>
<span class='del'>-    if (ui_current_win_type() != WIN_CONSOLE) {</span>
<span class='del'>-        status_bar_new(1);</span>
<span class='del'>-    }</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_prefs(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    if (args[0] == NULL) {</span>
<span class='del'>-        cons_prefs();</span>
<span class='del'>-        cons_show("Use the /account command for preferences for individual accounts.");</span>
<span class='del'>-    } else if (strcmp(args[0], "ui") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show_ui_prefs();</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    } else if (strcmp(args[0], "desktop") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show_desktop_prefs();</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    } else if (strcmp(args[0], "chat") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show_chat_prefs();</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    } else if (strcmp(args[0], "log") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show_log_prefs();</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    } else if (strcmp(args[0], "conn") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show_connection_prefs();</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    } else if (strcmp(args[0], "presence") == 0) {</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-        cons_show_presence_prefs();</span>
<span class='del'>-        cons_show("");</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_theme(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    // list themes</span>
<span class='del'>-    if (strcmp(args[0], "list") == 0) {</span>
<span class='del'>-        GSList *themes = theme_list();</span>
<span class='del'>-        cons_show_themes(themes);</span>
<span class='del'>-        g_slist_free_full(themes, g_free);</span>
<span class='del'>-</span>
<span class='del'>-    // load a theme</span>
<span class='del'>-    } else if (strcmp(args[0], "set") == 0) {</span>
<span class='del'>-        if (args[1] == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        } else if (theme_load(args[1])) {</span>
<span class='del'>-            ui_load_colours();</span>
<span class='del'>-            prefs_set_string(PREF_THEME, args[1]);</span>
<span class='del'>-            cons_show("Loaded theme: %s", args[1]);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Couldn't find theme: %s", args[1]);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_who(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-    } else {</span>
<span class='del'>-        char *presence = args[0];</span>
<span class='del'>-        char *group = NULL;</span>
<span class='del'>-        if ((g_strv_length(args) == 2) &amp;&amp; (args[1] != NULL)) {</span>
<span class='del'>-            group = args[1];</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        // bad arg</span>
<span class='del'>-        if ((presence != NULL)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "online") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "available") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "unavailable") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "offline") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "away") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "chat") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "xa") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "dnd") != 0)</span>
<span class='del'>-                &amp;&amp; (strcmp(presence, "any") != 0)) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-</span>
<span class='del'>-        // valid arg</span>
<span class='del'>-        } else {</span>
<span class='del'>-            if (win_type == WIN_MUC) {</span>
<span class='del'>-                if (group != NULL) {</span>
<span class='del'>-                    cons_show("The group argument is not valid when in a chat room.");</span>
<span class='del'>-                    return TRUE;</span>
<span class='del'>-                }</span>
<span class='del'>-</span>
<span class='del'>-                char *room = ui_current_recipient();</span>
<span class='del'>-                GList *list = muc_get_roster(room);</span>
<span class='del'>-</span>
<span class='del'>-                // no arg, show all contacts</span>
<span class='del'>-                if ((presence == NULL) || (g_strcmp0(presence, "any") == 0)) {</span>
<span class='del'>-                    ui_room_roster(room, list, NULL);</span>
<span class='del'>-</span>
<span class='del'>-                // available</span>
<span class='del'>-                } else if (strcmp("available", presence) == 0) {</span>
<span class='del'>-                    GList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (p_contact_is_available(contact)) {</span>
<span class='del'>-                            filtered = g_list_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_list_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    ui_room_roster(room, filtered, "available");</span>
<span class='del'>-</span>
<span class='del'>-                // unavailable</span>
<span class='del'>-                } else if (strcmp("unavailable", presence) == 0) {</span>
<span class='del'>-                    GList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (!p_contact_is_available(contact)) {</span>
<span class='del'>-                            filtered = g_list_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_list_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    ui_room_roster(room, filtered, "unavailable");</span>
<span class='del'>-</span>
<span class='del'>-                // online, available resources</span>
<span class='del'>-                } else if (strcmp("online", presence) == 0) {</span>
<span class='del'>-                    GList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (p_contact_has_available_resource(contact)) {</span>
<span class='del'>-                            filtered = g_list_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_list_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    ui_room_roster(room, filtered, "online");</span>
<span class='del'>-</span>
<span class='del'>-                // offline, no available resources</span>
<span class='del'>-                } else if (strcmp("offline", presence) == 0) {</span>
<span class='del'>-                    GList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (!p_contact_has_available_resource(contact)) {</span>
<span class='del'>-                            filtered = g_list_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_list_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    ui_room_roster(room, filtered, "offline");</span>
<span class='del'>-</span>
<span class='del'>-                // show specific status</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    GList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (strcmp(p_contact_presence(contact), presence) == 0) {</span>
<span class='del'>-                            filtered = g_list_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_list_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    ui_room_roster(room, filtered, presence);</span>
<span class='del'>-                }</span>
<span class='del'>-</span>
<span class='del'>-            // not in groupchat window</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("");</span>
<span class='del'>-                GSList *list = NULL;</span>
<span class='del'>-                if (group != NULL) {</span>
<span class='del'>-                    list = roster_get_group(group);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    list = roster_get_contacts();</span>
<span class='del'>-                }</span>
<span class='del'>-</span>
<span class='del'>-                // no arg, show all contacts</span>
<span class='del'>-                if ((presence == NULL) || (g_strcmp0(presence, "any") == 0)) {</span>
<span class='del'>-                    if (group != NULL) {</span>
<span class='del'>-                        cons_show("%s:", group);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        cons_show("All contacts:");</span>
<span class='del'>-                    }</span>
<span class='del'>-                    cons_show_contacts(list);</span>
<span class='del'>-</span>
<span class='del'>-                // available</span>
<span class='del'>-                } else if (strcmp("available", presence) == 0) {</span>
<span class='del'>-                    if (group != NULL) {</span>
<span class='del'>-                        cons_show("%s (%s):", group, presence);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        cons_show("Contacts (%s):", presence);</span>
<span class='del'>-                    }</span>
<span class='del'>-                    GSList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (p_contact_is_available(contact)) {</span>
<span class='del'>-                            filtered = g_slist_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_slist_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    cons_show_contacts(filtered);</span>
<span class='del'>-</span>
<span class='del'>-                // unavailable</span>
<span class='del'>-                } else if (strcmp("unavailable", presence) == 0) {</span>
<span class='del'>-                    if (group != NULL) {</span>
<span class='del'>-                        cons_show("%s (%s):", group, presence);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        cons_show("Contacts (%s):", presence);</span>
<span class='del'>-                    }</span>
<span class='del'>-                    GSList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (!p_contact_is_available(contact)) {</span>
<span class='del'>-                            filtered = g_slist_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_slist_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    cons_show_contacts(filtered);</span>
<span class='del'>-</span>
<span class='del'>-                // online, available resources</span>
<span class='del'>-                } else if (strcmp("online", presence) == 0) {</span>
<span class='del'>-                    if (group != NULL) {</span>
<span class='del'>-                        cons_show("%s (%s):", group, presence);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        cons_show("Contacts (%s):", presence);</span>
<span class='del'>-                    }</span>
<span class='del'>-                    GSList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (p_contact_has_available_resource(contact)) {</span>
<span class='del'>-                            filtered = g_slist_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_slist_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    cons_show_contacts(filtered);</span>
<span class='del'>-</span>
<span class='del'>-                // offline, no available resources</span>
<span class='del'>-                } else if (strcmp("offline", presence) == 0) {</span>
<span class='del'>-                    if (group != NULL) {</span>
<span class='del'>-                        cons_show("%s (%s):", group, presence);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        cons_show("Contacts (%s):", presence);</span>
<span class='del'>-                    }</span>
<span class='del'>-                    GSList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (!p_contact_has_available_resource(contact)) {</span>
<span class='del'>-                            filtered = g_slist_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_slist_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    cons_show_contacts(filtered);</span>
<span class='del'>-</span>
<span class='del'>-                // show specific status</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    if (group != NULL) {</span>
<span class='del'>-                        cons_show("%s (%s):", group, presence);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        cons_show("Contacts (%s):", presence);</span>
<span class='del'>-                    }</span>
<span class='del'>-                    GSList *filtered = NULL;</span>
<span class='del'>-</span>
<span class='del'>-                    while (list != NULL) {</span>
<span class='del'>-                        PContact contact = list-&gt;data;</span>
<span class='del'>-                        if (strcmp(p_contact_presence(contact), presence) == 0) {</span>
<span class='del'>-                            filtered = g_slist_append(filtered, contact);</span>
<span class='del'>-                        }</span>
<span class='del'>-                        list = g_slist_next(list);</span>
<span class='del'>-                    }</span>
<span class='del'>-</span>
<span class='del'>-                    cons_show_contacts(filtered);</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (win_type != WIN_CONSOLE &amp;&amp; win_type != WIN_MUC) {</span>
<span class='del'>-        status_bar_new(1);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_msg(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *usr = args[0];</span>
<span class='del'>-    char *msg = args[1];</span>
<span class='del'>-</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (win_type == WIN_MUC) {</span>
<span class='del'>-        char *room_name = ui_current_recipient();</span>
<span class='del'>-        if (muc_nick_in_roster(room_name, usr)) {</span>
<span class='del'>-            GString *full_jid = g_string_new(room_name);</span>
<span class='del'>-            g_string_append(full_jid, "/");</span>
<span class='del'>-            g_string_append(full_jid, usr);</span>
<span class='del'>-</span>
<span class='del'>-            if (msg != NULL) {</span>
<span class='del'>-                message_send(msg, full_jid-&gt;str);</span>
<span class='del'>-                ui_outgoing_msg("me", full_jid-&gt;str, msg);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                ui_new_chat_win(full_jid-&gt;str);</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            g_string_free(full_jid, TRUE);</span>
<span class='del'>-</span>
<span class='del'>-        } else {</span>
<span class='del'>-            ui_current_print_line("No such participant \"%s\" in room.", usr);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-</span>
<span class='del'>-    } else {</span>
<span class='del'>-        char *usr_jid = roster_barejid_from_name(usr);</span>
<span class='del'>-        if (usr_jid == NULL) {</span>
<span class='del'>-            usr_jid = usr;</span>
<span class='del'>-        }</span>
<span class='del'>-        if (msg != NULL) {</span>
<span class='del'>-#ifdef HAVE_LIBOTR</span>
<span class='del'>-            cons_debug("HAVE_LIBOTR, user_jid: %sm msg: %s", usr_jid, msg);</span>
<span class='del'>-            char *encrypted = otr_encrypt_message(usr_jid, msg);</span>
<span class='del'>-            message_send(encrypted, usr_jid);</span>
<span class='del'>-            otr_free_message(encrypted);</span>
<span class='del'>-#else</span>
<span class='del'>-            message_send(msg, usr_jid);</span>
<span class='del'>-#endif</span>
<span class='del'>-            ui_outgoing_msg("me", usr_jid, msg);</span>
<span class='del'>-</span>
<span class='del'>-            if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) &amp;&amp; prefs_get_boolean(PREF_CHLOG)) {</span>
<span class='del'>-                const char *jid = jabber_get_fulljid();</span>
<span class='del'>-                Jid *jidp = jid_create(jid);</span>
<span class='del'>-                chat_log_chat(jidp-&gt;barejid, usr_jid, msg, PROF_OUT_LOG, NULL);</span>
<span class='del'>-                jid_destroy(jidp);</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        } else {</span>
<span class='del'>-            const char * jid = NULL;</span>
<span class='del'>-</span>
<span class='del'>-            if (roster_barejid_from_name(usr_jid) != NULL) {</span>
<span class='del'>-                jid = roster_barejid_from_name(usr_jid);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                jid = usr_jid;</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            if (prefs_get_boolean(PREF_STATES)) {</span>
<span class='del'>-                if (!chat_session_exists(jid)) {</span>
<span class='del'>-                    chat_session_start(jid, TRUE);</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            ui_new_chat_win(usr_jid);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_group(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // list all groups</span>
<span class='del'>-    if (args[0] == NULL) {</span>
<span class='del'>-        GSList *groups = roster_get_groups();</span>
<span class='del'>-        GSList *curr = groups;</span>
<span class='del'>-        if (curr != NULL) {</span>
<span class='del'>-            cons_show("Groups:");</span>
<span class='del'>-            while (curr != NULL) {</span>
<span class='del'>-                cons_show("  %s", curr-&gt;data);</span>
<span class='del'>-                curr = g_slist_next(curr);</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            g_slist_free_full(groups, g_free);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("No groups.");</span>
<span class='del'>-        }</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // show contacts in group</span>
<span class='del'>-    if (strcmp(args[0], "show") == 0) {</span>
<span class='del'>-        char *group = args[1];</span>
<span class='del'>-        if (group == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        GSList *list = roster_get_group(group);</span>
<span class='del'>-        cons_show_roster_group(group, list);</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // add contact to group</span>
<span class='del'>-    if (strcmp(args[0], "add") == 0) {</span>
<span class='del'>-        char *group = args[1];</span>
<span class='del'>-        char *contact = args[2];</span>
<span class='del'>-</span>
<span class='del'>-        if ((group == NULL) || (contact == NULL)) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        char *barejid = roster_barejid_from_name(contact);</span>
<span class='del'>-        if (barejid == NULL) {</span>
<span class='del'>-            barejid = contact;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        PContact pcontact = roster_get_contact(barejid);</span>
<span class='del'>-        if (pcontact == NULL) {</span>
<span class='del'>-            cons_show("Contact not found in roster: %s", barejid);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        roster_add_to_group(group, barejid);</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // remove contact from group</span>
<span class='del'>-    if (strcmp(args[0], "remove") == 0) {</span>
<span class='del'>-        char *group = args[1];</span>
<span class='del'>-        char *contact = args[2];</span>
<span class='del'>-</span>
<span class='del'>-        if ((group == NULL) || (contact == NULL)) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        char *barejid = roster_barejid_from_name(contact);</span>
<span class='del'>-        if (barejid == NULL) {</span>
<span class='del'>-            barejid = contact;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        PContact pcontact = roster_get_contact(barejid);</span>
<span class='del'>-        if (pcontact == NULL) {</span>
<span class='del'>-            cons_show("Contact not found in roster: %s", barejid);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        roster_remove_from_group(group, barejid);</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_roster(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // show roster</span>
<span class='del'>-    if (args[0] == NULL) {</span>
<span class='del'>-        GSList *list = roster_get_contacts();</span>
<span class='del'>-        cons_show_roster(list);</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // add contact</span>
<span class='del'>-    if (strcmp(args[0], "add") == 0) {</span>
<span class='del'>-</span>
<span class='del'>-        if (args[1] == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        char *jid = args[1];</span>
<span class='del'>-        char *name = args[2];</span>
<span class='del'>-</span>
<span class='del'>-        roster_add_new(jid, name);</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // remove contact</span>
<span class='del'>-    if (strcmp(args[0], "remove") == 0) {</span>
<span class='del'>-</span>
<span class='del'>-        if (args[1] == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        char *jid = args[1];</span>
<span class='del'>-</span>
<span class='del'>-        roster_remove(jid);</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // change nickname</span>
<span class='del'>-    if (strcmp(args[0], "nick") == 0) {</span>
<span class='del'>-</span>
<span class='del'>-        if (args[1] == NULL) {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        char *jid = args[1];</span>
<span class='del'>-        char *name = args[2];</span>
<span class='del'>-</span>
<span class='del'>-        // contact does not exist</span>
<span class='del'>-        PContact contact = roster_get_contact(jid);</span>
<span class='del'>-        if (contact == NULL) {</span>
<span class='del'>-            cons_show("Contact not found in roster: %s", jid);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        roster_change_name(jid, name);</span>
<span class='del'>-</span>
<span class='del'>-        if (name == NULL) {</span>
<span class='del'>-            cons_show("Nickname for %s removed.", jid);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Nickname for %s set to: %s.", jid, name);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_duck(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *query = args[0];</span>
<span class='del'>-</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // if no duck win open, create it and send a help command</span>
<span class='del'>-    if (!ui_duck_exists()) {</span>
<span class='del'>-        ui_create_duck_win();</span>
<span class='del'>-</span>
<span class='del'>-        if (query != NULL) {</span>
<span class='del'>-            message_send_duck(query);</span>
<span class='del'>-            ui_duck(query);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-    // window exists, send query</span>
<span class='del'>-    } else {</span>
<span class='del'>-        ui_open_duck_win();</span>
<span class='del'>-</span>
<span class='del'>-        if (query != NULL) {</span>
<span class='del'>-            message_send_duck(query);</span>
<span class='del'>-            ui_duck(query);</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_status(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *usr = args[0];</span>
<span class='del'>-    char *usr_jid = NULL;</span>
<span class='del'>-</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    switch (win_type)</span>
<span class='del'>-    {</span>
<span class='del'>-        case WIN_MUC:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                ui_status_room(usr);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                ui_current_print_line("You must specify a nickname.");</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_CHAT:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                ui_current_print_line("No parameter required when in chat.");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                ui_status();</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_PRIVATE:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                ui_current_print_line("No parameter required when in chat.");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                ui_status_private();</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_CONSOLE:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                usr_jid = roster_barejid_from_name(usr);</span>
<span class='del'>-                if (usr_jid == NULL) {</span>
<span class='del'>-                    usr_jid = usr;</span>
<span class='del'>-                }</span>
<span class='del'>-                cons_show_status(usr_jid);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        default:</span>
<span class='del'>-            break;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_info(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *usr = args[0];</span>
<span class='del'>-    char *usr_jid = NULL;</span>
<span class='del'>-</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-    PContact pcontact = NULL;</span>
<span class='del'>-    char *recipient;</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    recipient = ui_current_recipient();</span>
<span class='del'>-</span>
<span class='del'>-    switch (win_type)</span>
<span class='del'>-    {</span>
<span class='del'>-        case WIN_MUC:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                pcontact = muc_get_participant(recipient, usr);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    cons_show_info(pcontact);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("No such participant \"%s\" in room.", usr);</span>
<span class='del'>-                }</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("No nickname supplied to /info in chat room.");</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_CHAT:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                cons_show("No parameter required for /info in chat.");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                pcontact = roster_get_contact(recipient);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    cons_show_info(pcontact);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("No such contact \"%s\" in roster.", recipient);</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_PRIVATE:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                ui_current_print_line("No parameter required when in chat.");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                Jid *jid = jid_create(recipient);</span>
<span class='del'>-                pcontact = muc_get_participant(jid-&gt;barejid, jid-&gt;resourcepart);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    cons_show_info(pcontact);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("No such participant \"%s\" in room.", jid-&gt;resourcepart);</span>
<span class='del'>-                }</span>
<span class='del'>-                jid_destroy(jid);</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_CONSOLE:</span>
<span class='del'>-            if (usr != NULL) {</span>
<span class='del'>-                usr_jid = roster_barejid_from_name(usr);</span>
<span class='del'>-                if (usr_jid == NULL) {</span>
<span class='del'>-                    usr_jid = usr;</span>
<span class='del'>-                }</span>
<span class='del'>-                pcontact = roster_get_contact(usr_jid);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    cons_show_info(pcontact);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("No such contact \"%s\" in roster.", usr);</span>
<span class='del'>-                }</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        default:</span>
<span class='del'>-            break;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_caps(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-    PContact pcontact = NULL;</span>
<span class='del'>-    char *recipient;</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    switch (win_type)</span>
<span class='del'>-    {</span>
<span class='del'>-        case WIN_MUC:</span>
<span class='del'>-            if (args[0] != NULL) {</span>
<span class='del'>-                recipient = ui_current_recipient();</span>
<span class='del'>-                pcontact = muc_get_participant(recipient, args[0]);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    Resource *resource = p_contact_get_resource(pcontact, args[0]);</span>
<span class='del'>-                    cons_show_caps(args[0], resource);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("No such participant \"%s\" in room.", args[0]);</span>
<span class='del'>-                }</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("No nickname supplied to /caps in chat room.");</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_CHAT:</span>
<span class='del'>-        case WIN_CONSOLE:</span>
<span class='del'>-            if (args[0] != NULL) {</span>
<span class='del'>-                Jid *jid = jid_create(args[0]);</span>
<span class='del'>-</span>
<span class='del'>-                if (jid-&gt;fulljid == NULL) {</span>
<span class='del'>-                    cons_show("You must provide a full jid to the /caps command.");</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    pcontact = roster_get_contact(jid-&gt;barejid);</span>
<span class='del'>-                    if (pcontact == NULL) {</span>
<span class='del'>-                        cons_show("Contact not found in roster: %s", jid-&gt;barejid);</span>
<span class='del'>-                    } else {</span>
<span class='del'>-                        Resource *resource = p_contact_get_resource(pcontact, jid-&gt;resourcepart);</span>
<span class='del'>-                        if (resource == NULL) {</span>
<span class='del'>-                            cons_show("Could not find resource %s, for contact %s", jid-&gt;barejid, jid-&gt;resourcepart);</span>
<span class='del'>-                        } else {</span>
<span class='del'>-                            cons_show_caps(jid-&gt;fulljid, resource);</span>
<span class='del'>-                        }</span>
<span class='del'>-                    }</span>
<span class='del'>-                }</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("You must provide a jid to the /caps command.");</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_PRIVATE:</span>
<span class='del'>-            if (args[0] != NULL) {</span>
<span class='del'>-                cons_show("No parameter needed to /caps when in private chat.");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                recipient = ui_current_recipient();</span>
<span class='del'>-                Jid *jid = jid_create(recipient);</span>
<span class='del'>-                if (jid) {</span>
<span class='del'>-                    pcontact = muc_get_participant(jid-&gt;barejid, jid-&gt;resourcepart);</span>
<span class='del'>-                    Resource *resource = p_contact_get_resource(pcontact, jid-&gt;resourcepart);</span>
<span class='del'>-                    cons_show_caps(jid-&gt;resourcepart, resource);</span>
<span class='del'>-                    jid_destroy(jid);</span>
<span class='del'>-                }</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        default:</span>
<span class='del'>-            break;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_software(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-    PContact pcontact = NULL;</span>
<span class='del'>-    char *recipient;</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    switch (win_type)</span>
<span class='del'>-    {</span>
<span class='del'>-        case WIN_MUC:</span>
<span class='del'>-            if (args[0] != NULL) {</span>
<span class='del'>-                recipient = ui_current_recipient();</span>
<span class='del'>-                pcontact = muc_get_participant(recipient, args[0]);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    Jid *jid = jid_create_from_bare_and_resource(recipient, args[0]);</span>
<span class='del'>-                    iq_send_software_version(jid-&gt;fulljid);</span>
<span class='del'>-                    jid_destroy(jid);</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    cons_show("No such participant \"%s\" in room.", args[0]);</span>
<span class='del'>-                }</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("No nickname supplied to /software in chat room.");</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_CHAT:</span>
<span class='del'>-        case WIN_CONSOLE:</span>
<span class='del'>-            if (args[0] != NULL) {</span>
<span class='del'>-                Jid *jid = jid_create(args[0]);</span>
<span class='del'>-</span>
<span class='del'>-                if (jid == NULL || jid-&gt;fulljid == NULL) {</span>
<span class='del'>-                    cons_show("You must provide a full jid to the /software command.");</span>
<span class='del'>-                } else {</span>
<span class='del'>-                    iq_send_software_version(jid-&gt;fulljid);</span>
<span class='del'>-                }</span>
<span class='del'>-                jid_destroy(jid);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("You must provide a jid to the /software command.");</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        case WIN_PRIVATE:</span>
<span class='del'>-            if (args[0] != NULL) {</span>
<span class='del'>-                cons_show("No parameter needed to /software when in private chat.");</span>
<span class='del'>-            } else {</span>
<span class='del'>-                recipient = ui_current_recipient();</span>
<span class='del'>-                iq_send_software_version(recipient);</span>
<span class='del'>-            }</span>
<span class='del'>-            break;</span>
<span class='del'>-        default:</span>
<span class='del'>-            break;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_join(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    Jid *room_arg = jid_create(args[0]);</span>
<span class='del'>-    if (room_arg == NULL) {</span>
<span class='del'>-        cons_show_error("Specified room has incorrect format");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    int num_args = g_strv_length(args);</span>
<span class='del'>-    char *room = NULL;</span>
<span class='del'>-    char *nick = NULL;</span>
<span class='del'>-    GString *room_str = g_string_new("");</span>
<span class='del'>-    Jid *my_jid = jid_create(jabber_get_fulljid());</span>
<span class='del'>-</span>
<span class='del'>-    // full room jid supplied (room@server)</span>
<span class='del'>-    if (room_arg-&gt;localpart != NULL) {</span>
<span class='del'>-        room = args[0];</span>
<span class='del'>-</span>
<span class='del'>-    // server not supplied (room), use account preference</span>
<span class='del'>-    } else {</span>
<span class='del'>-        g_string_append(room_str, args[0]);</span>
<span class='del'>-        g_string_append(room_str, "@");</span>
<span class='del'>-        g_string_append(room_str, account-&gt;muc_service);</span>
<span class='del'>-        room = room_str-&gt;str;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // nick supplied</span>
<span class='del'>-    if (num_args == 2) {</span>
<span class='del'>-        nick = args[1];</span>
<span class='del'>-</span>
<span class='del'>-    // otherwise use account preference</span>
<span class='del'>-    } else {</span>
<span class='del'>-        nick = account-&gt;muc_nick;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    Jid *room_jid = jid_create_from_bare_and_resource(room, nick);</span>
<span class='del'>-</span>
<span class='del'>-    if (!muc_room_is_active(room_jid)) {</span>
<span class='del'>-        presence_join_room(room_jid);</span>
<span class='del'>-    }</span>
<span class='del'>-    ui_room_join(room_jid);</span>
<span class='del'>-    muc_remove_invite(room);</span>
<span class='del'>-</span>
<span class='del'>-    jid_destroy(room_arg);</span>
<span class='del'>-    jid_destroy(room_jid);</span>
<span class='del'>-    jid_destroy(my_jid);</span>
<span class='del'>-    g_string_free(room_str, TRUE);</span>
<span class='del'>-    accounts_free_account(account);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_invite(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *contact = args[0];</span>
<span class='del'>-    char *reason = args[1];</span>
<span class='del'>-    char *room = NULL;</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (ui_current_win_type() != WIN_MUC) {</span>
<span class='del'>-        cons_show("You must be in a chat room to send an invite.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    char *usr_jid = roster_barejid_from_name(contact);</span>
<span class='del'>-    if (usr_jid == NULL) {</span>
<span class='del'>-        usr_jid = contact;</span>
<span class='del'>-    }</span>
<span class='del'>-    room = ui_current_recipient();</span>
<span class='del'>-    message_send_invite(room, usr_jid, reason);</span>
<span class='del'>-    if (reason != NULL) {</span>
<span class='del'>-        cons_show("Room invite sent, contact: %s, room: %s, reason: \"%s\".",</span>
<span class='del'>-            contact, room, reason);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Room invite sent, contact: %s, room: %s.",</span>
<span class='del'>-            contact, room);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_invites(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    GSList *invites = muc_get_invites();</span>
<span class='del'>-    cons_show_room_invites(invites);</span>
<span class='del'>-    g_slist_free_full(invites, g_free);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_decline(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    if (!muc_invites_include(args[0])) {</span>
<span class='del'>-        cons_show("No such invite exists.");</span>
<span class='del'>-    } else {</span>
<span class='del'>-        muc_remove_invite(args[0]);</span>
<span class='del'>-        cons_show("Declined invite to %s.", args[0]);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_rooms(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currenlty connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (args[0] == NULL) {</span>
<span class='del'>-        ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='del'>-        iq_room_list_request(account-&gt;muc_service);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        iq_room_list_request(args[0]);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_bookmark(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    gchar *cmd = args[0];</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currenlty connect.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    /* TODO: /bookmark list room@server */</span>
<span class='del'>-</span>
<span class='del'>-    if (cmd == NULL || strcmp(cmd, "list") == 0) {</span>
<span class='del'>-        cons_show_bookmarks(bookmark_get_list());</span>
<span class='del'>-    } else {</span>
<span class='del'>-        gboolean autojoin = FALSE;</span>
<span class='del'>-        gchar *jid = NULL;</span>
<span class='del'>-        gchar *nick = NULL;</span>
<span class='del'>-        int idx = 1;</span>
<span class='del'>-</span>
<span class='del'>-        while (args[idx] != NULL) {</span>
<span class='del'>-            gchar *opt = args[idx];</span>
<span class='del'>-</span>
<span class='del'>-            if (strcmp(opt, "autojoin") == 0) {</span>
<span class='del'>-                autojoin = TRUE;</span>
<span class='del'>-            } else if (jid == NULL) {</span>
<span class='del'>-                jid = opt;</span>
<span class='del'>-            } else if (nick == NULL) {</span>
<span class='del'>-                nick = opt;</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("Usage: %s", help.usage);</span>
<span class='del'>-            }</span>
<span class='del'>-</span>
<span class='del'>-            ++idx;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        if (jid == NULL) {</span>
<span class='del'>-            win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-</span>
<span class='del'>-            if (win_type == WIN_MUC) {</span>
<span class='del'>-                jid = ui_current_recipient();</span>
<span class='del'>-                nick = muc_get_room_nick(jid);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                cons_show("Usage: %s", help.usage);</span>
<span class='del'>-                return TRUE;</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        if (strcmp(cmd, "add") == 0) {</span>
<span class='del'>-            bookmark_add(jid, nick, autojoin);</span>
<span class='del'>-        } else if (strcmp(cmd, "remove") == 0) {</span>
<span class='del'>-            bookmark_remove(jid, autojoin);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_disco(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currenlty connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    GString *jid = g_string_new("");</span>
<span class='del'>-    if (args[1] != NULL) {</span>
<span class='del'>-        jid = g_string_append(jid, args[1]);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        Jid *jidp = jid_create(jabber_get_fulljid());</span>
<span class='del'>-        jid = g_string_append(jid, jidp-&gt;domainpart);</span>
<span class='del'>-        jid_destroy(jidp);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (g_strcmp0(args[0], "info") == 0) {</span>
<span class='del'>-        iq_disco_info_request(jid-&gt;str);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        iq_disco_items_request(jid-&gt;str);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    g_string_free(jid, TRUE);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_nick(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-    if (ui_current_win_type() != WIN_MUC) {</span>
<span class='del'>-        cons_show("You can only change your nickname in a chat room window.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    char *room = ui_current_recipient();</span>
<span class='del'>-    char *nick = args[0];</span>
<span class='del'>-    presence_change_room_nick(room, nick);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_tiny(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *url = args[0];</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-</span>
<span class='del'>-    if (!tinyurl_valid(url)) {</span>
<span class='del'>-        GString *error = g_string_new("/tiny, badly formed URL: ");</span>
<span class='del'>-        g_string_append(error, url);</span>
<span class='del'>-        cons_show_error(error-&gt;str);</span>
<span class='del'>-        if (win_type != WIN_CONSOLE) {</span>
<span class='del'>-            ui_current_error_line(error-&gt;str);</span>
<span class='del'>-        }</span>
<span class='del'>-        g_string_free(error, TRUE);</span>
<span class='del'>-    } else if (win_type != WIN_CONSOLE) {</span>
<span class='del'>-        char *tiny = tinyurl_get(url);</span>
<span class='del'>-</span>
<span class='del'>-        if (tiny != NULL) {</span>
<span class='del'>-            if (win_type == WIN_CHAT) {</span>
<span class='del'>-                char *recipient = ui_current_recipient();</span>
<span class='del'>-#ifdef HAVE_LIBOTR</span>
<span class='del'>-                char *encrypted = otr_encrypt_message(recipient, tiny);</span>
<span class='del'>-                message_send(encrypted, recipient);</span>
<span class='del'>-                otr_free_message(encrypted);</span>
<span class='del'>-#else</span>
<span class='del'>-                message_send(tiny, recipient);</span>
<span class='del'>-#endif</span>
<span class='del'>-</span>
<span class='del'>-                if (prefs_get_boolean(PREF_CHLOG)) {</span>
<span class='del'>-                    const char *jid = jabber_get_fulljid();</span>
<span class='del'>-                    Jid *jidp = jid_create(jid);</span>
<span class='del'>-                    chat_log_chat(jidp-&gt;barejid, recipient, tiny, PROF_OUT_LOG, NULL);</span>
<span class='del'>-                    jid_destroy(jidp);</span>
<span class='del'>-                }</span>
<span class='del'>-</span>
<span class='del'>-                ui_outgoing_msg("me", recipient, tiny);</span>
<span class='del'>-            } else if (win_type == WIN_PRIVATE) {</span>
<span class='del'>-                char *recipient = ui_current_recipient();</span>
<span class='del'>-                message_send(tiny, recipient);</span>
<span class='del'>-                ui_outgoing_msg("me", recipient, tiny);</span>
<span class='del'>-            } else { // groupchat</span>
<span class='del'>-                char *recipient = ui_current_recipient();</span>
<span class='del'>-                message_send_groupchat(tiny, recipient);</span>
<span class='del'>-            }</span>
<span class='del'>-            free(tiny);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show_error("Couldn't get tinyurl.");</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("/tiny can only be used in chat windows");</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_clear(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    ui_clear_current();</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_close(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    int index = 0;</span>
<span class='del'>-    int count = 0;</span>
<span class='del'>-</span>
<span class='del'>-    if (args[0] == NULL) {</span>
<span class='del'>-        index = ui_current_win_index();</span>
<span class='del'>-    } else if (strcmp(args[0], "all") == 0) {</span>
<span class='del'>-        count = ui_close_all_wins();</span>
<span class='del'>-        if (count == 0) {</span>
<span class='del'>-            cons_show("No windows to close.");</span>
<span class='del'>-        } else if (count == 1) {</span>
<span class='del'>-            cons_show("Closed 1 window.");</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Closed %d windows.", count);</span>
<span class='del'>-        }</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    } else if (strcmp(args[0], "read") == 0) {</span>
<span class='del'>-        count = ui_close_read_wins();</span>
<span class='del'>-        if (count == 0) {</span>
<span class='del'>-            cons_show("No windows to close.");</span>
<span class='del'>-        } else if (count == 1) {</span>
<span class='del'>-            cons_show("Closed 1 window.");</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Closed %d windows.", count);</span>
<span class='del'>-        }</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    } else {</span>
<span class='del'>-        index = atoi(args[0]);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (index &lt; 0 || index == 10) {</span>
<span class='del'>-        cons_show("No such window exists.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (index == 1) {</span>
<span class='del'>-        cons_show("Cannot close console window.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (index == 0) {</span>
<span class='del'>-        index = 10;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (!ui_win_exists(index)) {</span>
<span class='del'>-        cons_show("Window is not open.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // handle leaving rooms, or chat</span>
<span class='del'>-    if (conn_status == JABBER_CONNECTED) {</span>
<span class='del'>-        ui_close_connected_win(index);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // close the window</span>
<span class='del'>-    ui_close_win(index);</span>
<span class='del'>-    cons_show("Closed window %d", index);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_leave(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-    win_type_t win_type = ui_current_win_type();</span>
<span class='del'>-    int index = ui_current_win_index();</span>
<span class='del'>-</span>
<span class='del'>-    if (win_type != WIN_MUC) {</span>
<span class='del'>-        cons_show("You can only use the /leave command in a chat room.");</span>
<span class='del'>-        cons_alert();</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // handle leaving rooms, or chat</span>
<span class='del'>-    if (conn_status == JABBER_CONNECTED) {</span>
<span class='del'>-        ui_close_connected_win(index);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // close the window</span>
<span class='del'>-    ui_close_win(index);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_beep(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    return _cmd_set_boolean_preference(args[0], help, "Sound", PREF_BEEP);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_states(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean result = _cmd_set_boolean_preference(args[0], help, "Sending chat states",</span>
<span class='del'>-        PREF_STATES);</span>
<span class='del'>-</span>
<span class='del'>-    // if disabled, disable outtype and gone</span>
<span class='del'>-    if (result == TRUE &amp;&amp; (strcmp(args[0], "off") == 0)) {</span>
<span class='del'>-        prefs_set_boolean(PREF_OUTTYPE, FALSE);</span>
<span class='del'>-        prefs_set_gone(0);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_titlebar(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    if (strcmp(args[0], "version") != 0) {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    } else {</span>
<span class='del'>-        return _cmd_set_boolean_preference(args[1], help,</span>
<span class='del'>-        "Show version in window title", PREF_TITLEBARVERSION);</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_outtype(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Sending typing notifications", PREF_OUTTYPE);</span>
<span class='del'>-</span>
<span class='del'>-    // if enabled, enable states</span>
<span class='del'>-    if (result == TRUE &amp;&amp; (strcmp(args[0], "on") == 0)) {</span>
<span class='del'>-        prefs_set_boolean(PREF_STATES, TRUE);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_otr(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-#ifdef HAVE_LIBOTR</span>
<span class='del'>-    if (strcmp(args[0], "gen") == 0) {</span>
<span class='del'>-        if (jabber_get_connection_status() != JABBER_CONNECTED) {</span>
<span class='del'>-            cons_show("You must be connected with an account to load OTR information.");</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        } else {</span>
<span class='del'>-            ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='del'>-            otr_account_load(account);</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-#else</span>
<span class='del'>-    cons_show("This version of Profanity has not been build with OTR support enabled");</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-#endif</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_gone(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *value = args[0];</span>
<span class='del'>-</span>
<span class='del'>-    gint period = atoi(value);</span>
<span class='del'>-    prefs_set_gone(period);</span>
<span class='del'>-    if (period == 0) {</span>
<span class='del'>-        cons_show("Automatic leaving conversations after period disabled.");</span>
<span class='del'>-    } else if (period == 1) {</span>
<span class='del'>-        cons_show("Leaving conversations after 1 minute of inactivity.");</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Leaving conversations after %d minutes of inactivity.", period);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // if enabled, enable states</span>
<span class='del'>-    if (period &gt; 0) {</span>
<span class='del'>-        prefs_set_boolean(PREF_STATES, TRUE);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_notify(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *kind = args[0];</span>
<span class='del'>-    char *value = args[1];</span>
<span class='del'>-</span>
<span class='del'>-    // bad kind</span>
<span class='del'>-    if ((strcmp(kind, "message") != 0) &amp;&amp; (strcmp(kind, "typing") != 0) &amp;&amp;</span>
<span class='del'>-            (strcmp(kind, "remind") != 0) &amp;&amp; (strcmp(kind, "invite") != 0) &amp;&amp;</span>
<span class='del'>-            (strcmp(kind, "sub") != 0)) {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-</span>
<span class='del'>-    // set message setting</span>
<span class='del'>-    } else if (strcmp(kind, "message") == 0) {</span>
<span class='del'>-        if (strcmp(value, "on") == 0) {</span>
<span class='del'>-            cons_show("Message notifications enabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_MESSAGE, TRUE);</span>
<span class='del'>-        } else if (strcmp(value, "off") == 0) {</span>
<span class='del'>-            cons_show("Message notifications disabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_MESSAGE, FALSE);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Usage: /notify message on|off");</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-    // set typing setting</span>
<span class='del'>-    } else if (strcmp(kind, "typing") == 0) {</span>
<span class='del'>-        if (strcmp(value, "on") == 0) {</span>
<span class='del'>-            cons_show("Typing notifications enabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_TYPING, TRUE);</span>
<span class='del'>-        } else if (strcmp(value, "off") == 0) {</span>
<span class='del'>-            cons_show("Typing notifications disabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_TYPING, FALSE);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Usage: /notify typing on|off");</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-    // set invite setting</span>
<span class='del'>-    } else if (strcmp(kind, "invite") == 0) {</span>
<span class='del'>-        if (strcmp(value, "on") == 0) {</span>
<span class='del'>-            cons_show("Chat room invite notifications enabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_INVITE, TRUE);</span>
<span class='del'>-        } else if (strcmp(value, "off") == 0) {</span>
<span class='del'>-            cons_show("Chat room invite notifications disabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_INVITE, FALSE);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Usage: /notify invite on|off");</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-    // set subscription setting</span>
<span class='del'>-    } else if (strcmp(kind, "sub") == 0) {</span>
<span class='del'>-        if (strcmp(value, "on") == 0) {</span>
<span class='del'>-            cons_show("Subscription notifications enabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_SUB, TRUE);</span>
<span class='del'>-        } else if (strcmp(value, "off") == 0) {</span>
<span class='del'>-            cons_show("Subscription notifications disabled.");</span>
<span class='del'>-            prefs_set_boolean(PREF_NOTIFY_SUB, FALSE);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Usage: /notify sub on|off");</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-    // set remind setting</span>
<span class='del'>-    } else if (strcmp(kind, "remind") == 0) {</span>
<span class='del'>-        gint period = atoi(value);</span>
<span class='del'>-        prefs_set_notify_remind(period);</span>
<span class='del'>-        if (period == 0) {</span>
<span class='del'>-            cons_show("Message reminders disabled.");</span>
<span class='del'>-        } else if (period == 1) {</span>
<span class='del'>-            cons_show("Message reminder period set to 1 second.");</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Message reminder period set to %d seconds.", period);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Unknown command: %s.", kind);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_log(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *subcmd = args[0];</span>
<span class='del'>-    char *value = args[1];</span>
<span class='del'>-    int intval;</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(subcmd, "maxsize") == 0) {</span>
<span class='del'>-        if (_strtoi(value, &amp;intval, PREFS_MIN_LOG_SIZE, INT_MAX) == 0) {</span>
<span class='del'>-            prefs_set_max_log_size(intval);</span>
<span class='del'>-            cons_show("Log maxinum size set to %d bytes", intval);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    /* TODO: make 'level' subcommand for debug level */</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_reconnect(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *value = args[0];</span>
<span class='del'>-    int intval;</span>
<span class='del'>-</span>
<span class='del'>-    if (_strtoi(value, &amp;intval, 0, INT_MAX) == 0) {</span>
<span class='del'>-        prefs_set_reconnect(intval);</span>
<span class='del'>-        if (intval == 0) {</span>
<span class='del'>-            cons_show("Reconnect disabled.", intval);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Reconnect interval set to %d seconds.", intval);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_autoping(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *value = args[0];</span>
<span class='del'>-    int intval;</span>
<span class='del'>-</span>
<span class='del'>-    if (_strtoi(value, &amp;intval, 0, INT_MAX) == 0) {</span>
<span class='del'>-        prefs_set_autoping(intval);</span>
<span class='del'>-        jabber_set_autoping(intval);</span>
<span class='del'>-        if (intval == 0) {</span>
<span class='del'>-            cons_show("Autoping disabled.", intval);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Autoping interval set to %d seconds.", intval);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_autoaway(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    char *setting = args[0];</span>
<span class='del'>-    char *value = args[1];</span>
<span class='del'>-    int minutesval;</span>
<span class='del'>-</span>
<span class='del'>-    if ((strcmp(setting, "mode") != 0) &amp;&amp; (strcmp(setting, "time") != 0) &amp;&amp;</span>
<span class='del'>-            (strcmp(setting, "message") != 0) &amp;&amp; (strcmp(setting, "check") != 0)) {</span>
<span class='del'>-        cons_show("Setting must be one of 'mode', 'time', 'message' or 'check'");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(setting, "mode") == 0) {</span>
<span class='del'>-        if ((strcmp(value, "idle") != 0) &amp;&amp; (strcmp(value, "away") != 0) &amp;&amp;</span>
<span class='del'>-                (strcmp(value, "off") != 0)) {</span>
<span class='del'>-            cons_show("Mode must be one of 'idle', 'away' or 'off'");</span>
<span class='del'>-        } else {</span>
<span class='del'>-            prefs_set_string(PREF_AUTOAWAY_MODE, value);</span>
<span class='del'>-            cons_show("Auto away mode set to: %s.", value);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(setting, "time") == 0) {</span>
<span class='del'>-        if (_strtoi(value, &amp;minutesval, 1, INT_MAX) == 0) {</span>
<span class='del'>-            prefs_set_autoaway_time(minutesval);</span>
<span class='del'>-            cons_show("Auto away time set to: %d minutes.", minutesval);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(setting, "message") == 0) {</span>
<span class='del'>-        if (strcmp(value, "off") == 0) {</span>
<span class='del'>-            prefs_set_string(PREF_AUTOAWAY_MESSAGE, NULL);</span>
<span class='del'>-            cons_show("Auto away message cleared.");</span>
<span class='del'>-        } else {</span>
<span class='del'>-            prefs_set_string(PREF_AUTOAWAY_MESSAGE, value);</span>
<span class='del'>-            cons_show("Auto away message set to: \"%s\".", value);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(setting, "check") == 0) {</span>
<span class='del'>-        return _cmd_set_boolean_preference(value, help, "Online check",</span>
<span class='del'>-            PREF_AUTOAWAY_CHECK);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_priority(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    char *value = args[0];</span>
<span class='del'>-    int intval;</span>
<span class='del'>-</span>
<span class='del'>-    if (_strtoi(value, &amp;intval, -128, 127) == 0) {</span>
<span class='del'>-        accounts_set_priority_all(jabber_get_account_name(), intval);</span>
<span class='del'>-        resource_presence_t last_presence = accounts_get_last_presence(jabber_get_account_name());</span>
<span class='del'>-        presence_update(last_presence, jabber_get_presence_message(), 0);</span>
<span class='del'>-        cons_show("Priority set to %d.", intval);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_statuses(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Status notifications", PREF_STATUSES);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_vercheck(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    int num_args = g_strv_length(args);</span>
<span class='del'>-</span>
<span class='del'>-    if (num_args == 0) {</span>
<span class='del'>-        cons_check_version(TRUE);</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    } else {</span>
<span class='del'>-        return _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-            "Version checking", PREF_VERCHECK);</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_flash(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Screen flash", PREF_FLASH);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_intype(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Show contact typing", PREF_INTYPE);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_splash(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Splash screen", PREF_SPLASH);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_autoconnect(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    if (strcmp(args[0], "off") == 0) {</span>
<span class='del'>-        prefs_set_string(PREF_CONNECT_ACCOUNT, NULL);</span>
<span class='del'>-        cons_show("Autoconnect account disabled.");</span>
<span class='del'>-    } else if (strcmp(args[0], "set") == 0) {</span>
<span class='del'>-        prefs_set_string(PREF_CONNECT_ACCOUNT, args[1]);</span>
<span class='del'>-        cons_show("Autoconnect account set to: %s.", args[1]);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        cons_show("Usage: %s", help.usage);</span>
<span class='del'>-    }</span>
<span class='del'>-    return true;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_chlog(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Chat logging", PREF_CHLOG);</span>
<span class='del'>-</span>
<span class='del'>-    // if set to off, disable history</span>
<span class='del'>-    if (result == TRUE &amp;&amp; (strcmp(args[0], "off") == 0)) {</span>
<span class='del'>-        prefs_set_boolean(PREF_HISTORY, FALSE);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_grlog(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Groupchat logging", PREF_GRLOG);</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_mouse(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Mouse handling", PREF_MOUSE);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_history(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='del'>-        "Chat history", PREF_HISTORY);</span>
<span class='del'>-</span>
<span class='del'>-    // if set to on, set chlog</span>
<span class='del'>-    if (result == TRUE &amp;&amp; (strcmp(args[0], "on") == 0)) {</span>
<span class='del'>-        prefs_set_boolean(PREF_CHLOG, TRUE);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_away(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    _update_presence(RESOURCE_AWAY, "away", args);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_online(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    _update_presence(RESOURCE_ONLINE, "online", args);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_dnd(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    _update_presence(RESOURCE_DND, "dnd", args);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_chat(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    _update_presence(RESOURCE_CHAT, "chat", args);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_xa(gchar **args, struct cmd_help_t help)</span>
<span class='del'>-{</span>
<span class='del'>-    _update_presence(RESOURCE_XA, "xa", args);</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-// helper function that asks the user for a password and saves it in passwd</span>
<span class='del'>-</span>
<span class='del'>-static char *</span>
<span class='del'>-_ask_password(void) {</span>
<span class='del'>-  char *passwd = malloc(sizeof(char) * (MAX_PASSWORD_SIZE + 1));</span>
<span class='del'>-  status_bar_get_password();</span>
<span class='del'>-  status_bar_refresh();</span>
<span class='del'>-  inp_block();</span>
<span class='del'>-  inp_get_password(passwd);</span>
<span class='del'>-  inp_non_block();</span>
<span class='del'>-</span>
<span class='del'>-  return passwd;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-// helper function for status change commands</span>
<span class='del'>-</span>
<span class='del'>-static void</span>
<span class='del'>-_update_presence(const resource_presence_t resource_presence,</span>
<span class='del'>-    const char * const show, gchar **args)</span>
<span class='del'>-{</span>
<span class='del'>-    char *msg = NULL;</span>
<span class='del'>-    int num_args = g_strv_length(args);</span>
<span class='del'>-    if (num_args == 1) {</span>
<span class='del'>-        msg = args[0];</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='del'>-</span>
<span class='del'>-    if (conn_status != JABBER_CONNECTED) {</span>
<span class='del'>-        cons_show("You are not currently connected.");</span>
<span class='del'>-    } else {</span>
<span class='del'>-        presence_update(resource_presence, msg, 0);</span>
<span class='del'>-</span>
<span class='del'>-        contact_presence_t contact_presence = contact_presence_from_resource_presence(resource_presence);</span>
<span class='del'>-        title_bar_set_status(contact_presence);</span>
<span class='del'>-</span>
<span class='del'>-        gint priority = accounts_get_priority_for_presence_type(jabber_get_account_name(), resource_presence);</span>
<span class='del'>-        if (msg != NULL) {</span>
<span class='del'>-            cons_show("Status set to %s (priority %d), \"%s\".", show, priority, msg);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            cons_show("Status set to %s (priority %d).", show, priority);</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-// helper function for boolean preference commands</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help,</span>
<span class='del'>-    const char * const display, preference_t pref)</span>
<span class='del'>-{</span>
<span class='del'>-    GString *enabled = g_string_new(display);</span>
<span class='del'>-    g_string_append(enabled, " enabled.");</span>
<span class='del'>-</span>
<span class='del'>-    GString *disabled = g_string_new(display);</span>
<span class='del'>-    g_string_append(disabled, " disabled.");</span>
<span class='del'>-</span>
<span class='del'>-    if (strcmp(arg, "on") == 0) {</span>
<span class='del'>-        cons_show(enabled-&gt;str);</span>
<span class='del'>-        prefs_set_boolean(pref, TRUE);</span>
<span class='del'>-    } else if (strcmp(arg, "off") == 0) {</span>
<span class='del'>-        cons_show(disabled-&gt;str);</span>
<span class='del'>-        prefs_set_boolean(pref, FALSE);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        char usage[strlen(help.usage) + 8];</span>
<span class='del'>-        sprintf(usage, "Usage: %s", help.usage);</span>
<span class='del'>-        cons_show(usage);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    g_string_free(enabled, TRUE);</span>
<span class='del'>-    g_string_free(disabled, TRUE);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='ctx'> static char *</span>
<span class='ctx'> _sub_autocomplete(char *input, int *size)</span>
<span class='ctx'> {</span>
<span class='hunk'>@@ -4029,23 +1595,3 @@ _account_autocomplete(char *input, int *size)</span>
<span class='ctx'>     return NULL;</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static int</span>
<span class='del'>-_strtoi(char *str, int *saveptr, int min, int max)</span>
<span class='del'>-{</span>
<span class='del'>-    char *ptr;</span>
<span class='del'>-    int val;</span>
<span class='del'>-</span>
<span class='del'>-    errno = 0;</span>
<span class='del'>-    val = (int)strtol(str, &amp;ptr, 0);</span>
<span class='del'>-    if (*str == '\0' || *ptr != '\0') {</span>
<span class='del'>-        cons_show("Illegal character. Must be a number.");</span>
<span class='del'>-        return -1;</span>
<span class='del'>-    } else if (errno == ERANGE || val &lt; min || val &gt; max) {</span>
<span class='del'>-        cons_show("Value out of range. Must be in %d..%d.", min, max);</span>
<span class='del'>-        return -1;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    *saveptr = val;</span>
<span class='del'>-</span>
<span class='del'>-    return 0;</span>
<span class='del'>-}</span>
<span class='head'>diff --git a/src/command/command.h b/src/command/command.h
index c20413c8..f958c0d1 100644
--- a/<a href='/danisanti/profani-tty/tree/src/command/command.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/command/command.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/command/command.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/command.h</a>
</span><span class='hunk'>@@ -25,15 +25,10 @@</span>
<span class='ctx'> </span>
<span class='ctx'> #include &lt;glib.h&gt;</span>
<span class='ctx'> </span>
<span class='del'>-// Command help strings</span>
<span class='del'>-typedef struct cmd_help_t {</span>
<span class='del'>-    const gchar *usage;</span>
<span class='del'>-    const gchar *short_help;</span>
<span class='del'>-    const gchar *long_help[50];</span>
<span class='del'>-} CommandHelp;</span>
<span class='add'>+GHashTable *commands;</span>
<span class='ctx'> </span>
<span class='ctx'> void cmd_init(void);</span>
<span class='del'>-void cmd_close(void);</span>
<span class='add'>+void cmd_uninit(void);</span>
<span class='ctx'> </span>
<span class='ctx'> void cmd_autocomplete(char *input, int *size);</span>
<span class='ctx'> void cmd_reset_autocomplete(void);</span>
<span class='head'>diff --git a/src/command/commands.c b/src/command/commands.c
new file mode 100644
index 00000000..5babefe8
--- /dev/null
+++ b/<a href='/danisanti/profani-tty/tree/src/command/commands.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/commands.c</a>
</span><span class='hunk'>@@ -0,0 +1,2409 @@</span>
<span class='add'>+/*</span>
<span class='add'>+ * commands.c</span>
<span class='add'>+ *</span>
<span class='add'>+ * Copyright (C) 2012, 2013 James Booth &lt;boothj5@gmail.com&gt;</span>
<span class='add'>+ *</span>
<span class='add'>+ * This file is part of Profanity.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is free software: you can redistribute it and/or modify</span>
<span class='add'>+ * it under the terms of the GNU General Public License as published by</span>
<span class='add'>+ * the Free Software Foundation, either version 3 of the License, or</span>
<span class='add'>+ * (at your option) any later version.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is distributed in the hope that it will be useful,</span>
<span class='add'>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class='add'>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class='add'>+ * GNU General Public License for more details.</span>
<span class='add'>+ *</span>
<span class='add'>+ * You should have received a copy of the GNU General Public License</span>
<span class='add'>+ * along with Profanity.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class='add'>+ *</span>
<span class='add'>+ */</span>
<span class='add'>+</span>
<span class='add'>+#include &lt;string.h&gt;</span>
<span class='add'>+#include &lt;stdlib.h&gt;</span>
<span class='add'>+#include &lt;errno.h&gt;</span>
<span class='add'>+#include &lt;glib.h&gt;</span>
<span class='add'>+</span>
<span class='add'>+#include "chat_session.h"</span>
<span class='add'>+#include "command/commands.h"</span>
<span class='add'>+#include "common.h"</span>
<span class='add'>+#include "config/accounts.h"</span>
<span class='add'>+#include "config/preferences.h"</span>
<span class='add'>+#include "config/theme.h"</span>
<span class='add'>+#include "contact.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='add'>+#include "jid.h"</span>
<span class='add'>+#include "log.h"</span>
<span class='add'>+#include "muc.h"</span>
<span class='add'>+#include "otr.h"</span>
<span class='add'>+#include "profanity.h"</span>
<span class='add'>+#include "tools/autocomplete.h"</span>
<span class='add'>+#include "tools/parser.h"</span>
<span class='add'>+#include "tools/tinyurl.h"</span>
<span class='add'>+#include "ui/ui.h"</span>
<span class='add'>+#include "xmpp/xmpp.h"</span>
<span class='add'>+#include "xmpp/bookmark.h"</span>
<span class='add'>+</span>
<span class='add'>+static char * _ask_password(void);</span>
<span class='add'>+static void _update_presence(const resource_presence_t presence,</span>
<span class='add'>+    const char * const show, gchar **args);</span>
<span class='add'>+static gboolean _cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help,</span>
<span class='add'>+    const char * const display, preference_t pref);</span>
<span class='add'>+static int _strtoi(char *str, int *saveptr, int min, int max);</span>
<span class='add'>+static void _cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size);</span>
<span class='add'>+static gint _compare_commands(Command *a, Command *b);</span>
<span class='add'>+</span>
<span class='add'>+extern GHashTable *commands;</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_connect(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean result = FALSE;</span>
<span class='add'>+</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if ((conn_status != JABBER_DISCONNECTED) &amp;&amp; (conn_status != JABBER_STARTED)) {</span>
<span class='add'>+        cons_show("You are either connected already, or a login is in process.");</span>
<span class='add'>+        result = TRUE;</span>
<span class='add'>+    } else {</span>
<span class='add'>+        char *user = args[0];</span>
<span class='add'>+        char *altdomain = args[1];</span>
<span class='add'>+        char *lower = g_utf8_strdown(user, -1);</span>
<span class='add'>+        char *jid;</span>
<span class='add'>+</span>
<span class='add'>+        ProfAccount *account = accounts_get_account(lower);</span>
<span class='add'>+        if (account != NULL) {</span>
<span class='add'>+            if (account-&gt;resource != NULL) {</span>
<span class='add'>+                jid = create_fulljid(account-&gt;jid, account-&gt;resource);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                jid = strdup(account-&gt;jid);</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            if (account-&gt;password == NULL) {</span>
<span class='add'>+                account-&gt;password = _ask_password();</span>
<span class='add'>+            }</span>
<span class='add'>+            cons_show("Connecting with account %s as %s", account-&gt;name, jid);</span>
<span class='add'>+            conn_status = jabber_connect_with_account(account);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            char *passwd = _ask_password();</span>
<span class='add'>+            jid = strdup(lower);</span>
<span class='add'>+            cons_show("Connecting as %s", jid);</span>
<span class='add'>+            conn_status = jabber_connect_with_details(jid, passwd, altdomain);</span>
<span class='add'>+            free(passwd);</span>
<span class='add'>+        }</span>
<span class='add'>+        g_free(lower);</span>
<span class='add'>+</span>
<span class='add'>+        if (conn_status == JABBER_DISCONNECTED) {</span>
<span class='add'>+            cons_show_error("Connection attempt for %s failed.", jid);</span>
<span class='add'>+            log_debug("Connection attempt for %s failed", jid);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        accounts_free_account(account);</span>
<span class='add'>+        free(jid);</span>
<span class='add'>+</span>
<span class='add'>+        result = TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_account(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *command = args[0];</span>
<span class='add'>+</span>
<span class='add'>+    if (command == NULL) {</span>
<span class='add'>+        if (jabber_get_connection_status() != JABBER_CONNECTED) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='add'>+            cons_show_account(account);</span>
<span class='add'>+            accounts_free_account(account);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "list") == 0) {</span>
<span class='add'>+        gchar **accounts = accounts_get_list();</span>
<span class='add'>+        cons_show_account_list(accounts);</span>
<span class='add'>+        g_strfreev(accounts);</span>
<span class='add'>+    } else if (strcmp(command, "show") == 0) {</span>
<span class='add'>+        char *account_name = args[1];</span>
<span class='add'>+        if (account_name == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            ProfAccount *account = accounts_get_account(account_name);</span>
<span class='add'>+            if (account == NULL) {</span>
<span class='add'>+                cons_show("No such account.");</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show_account(account);</span>
<span class='add'>+                accounts_free_account(account);</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "add") == 0) {</span>
<span class='add'>+        char *account_name = args[1];</span>
<span class='add'>+        if (account_name == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            accounts_add(account_name, NULL);</span>
<span class='add'>+            cons_show("Account created.");</span>
<span class='add'>+            cons_show("");</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "enable") == 0) {</span>
<span class='add'>+        char *account_name = args[1];</span>
<span class='add'>+        if (account_name == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            if (accounts_enable(account_name)) {</span>
<span class='add'>+                cons_show("Account enabled.");</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("No such account: %s", account_name);</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "disable") == 0) {</span>
<span class='add'>+        char *account_name = args[1];</span>
<span class='add'>+        if (account_name == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            if (accounts_disable(account_name)) {</span>
<span class='add'>+                cons_show("Account disabled.");</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("No such account: %s", account_name);</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "rename") == 0) {</span>
<span class='add'>+        if (g_strv_length(args) != 3) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            char *account_name = args[1];</span>
<span class='add'>+            char *new_name = args[2];</span>
<span class='add'>+</span>
<span class='add'>+            if (accounts_rename(account_name, new_name)) {</span>
<span class='add'>+                cons_show("Account renamed.");</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("Either account %s doesn't exist, or account %s already exists.", account_name, new_name);</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "set") == 0) {</span>
<span class='add'>+        if (g_strv_length(args) != 4) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            char *account_name = args[1];</span>
<span class='add'>+            char *property = args[2];</span>
<span class='add'>+            char *value = args[3];</span>
<span class='add'>+</span>
<span class='add'>+            if (!accounts_account_exists(account_name)) {</span>
<span class='add'>+                cons_show("Account %s doesn't exist", account_name);</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                if (strcmp(property, "jid") == 0) {</span>
<span class='add'>+                    Jid *jid = jid_create(args[3]);</span>
<span class='add'>+                    if (jid == NULL) {</span>
<span class='add'>+                        cons_show("Malformed jid: %s", value);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        accounts_set_jid(account_name, jid-&gt;barejid);</span>
<span class='add'>+                        cons_show("Updated jid for account %s: %s", account_name, jid-&gt;barejid);</span>
<span class='add'>+                        if (jid-&gt;resourcepart != NULL) {</span>
<span class='add'>+                            accounts_set_resource(account_name, jid-&gt;resourcepart);</span>
<span class='add'>+                            cons_show("Updated resource for account %s: %s", account_name, jid-&gt;resourcepart);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        cons_show("");</span>
<span class='add'>+                    }</span>
<span class='add'>+                    jid_destroy(jid);</span>
<span class='add'>+                } else if (strcmp(property, "server") == 0) {</span>
<span class='add'>+                    accounts_set_server(account_name, value);</span>
<span class='add'>+                    cons_show("Updated server for account %s: %s", account_name, value);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else if (strcmp(property, "resource") == 0) {</span>
<span class='add'>+                    accounts_set_resource(account_name, value);</span>
<span class='add'>+                    cons_show("Updated resource for account %s: %s", account_name, value);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else if (strcmp(property, "password") == 0) {</span>
<span class='add'>+                    accounts_set_password(account_name, value);</span>
<span class='add'>+                    cons_show("Updated password for account %s", account_name);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else if (strcmp(property, "muc") == 0) {</span>
<span class='add'>+                    accounts_set_muc_service(account_name, value);</span>
<span class='add'>+                    cons_show("Updated muc service for account %s: %s", account_name, value);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else if (strcmp(property, "nick") == 0) {</span>
<span class='add'>+                    accounts_set_muc_nick(account_name, value);</span>
<span class='add'>+                    cons_show("Updated muc nick for account %s: %s", account_name, value);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else if (strcmp(property, "status") == 0) {</span>
<span class='add'>+                    if (!valid_resource_presence_string(value) &amp;&amp; (strcmp(value, "last") != 0)) {</span>
<span class='add'>+                        cons_show("Invalid status: %s", value);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        accounts_set_login_presence(account_name, value);</span>
<span class='add'>+                        cons_show("Updated login status for account %s: %s", account_name, value);</span>
<span class='add'>+                    }</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else if (valid_resource_presence_string(property)) {</span>
<span class='add'>+                        int intval;</span>
<span class='add'>+</span>
<span class='add'>+                        if (_strtoi(value, &amp;intval, -128, 127) == 0) {</span>
<span class='add'>+                            resource_presence_t presence_type = resource_presence_from_string(property);</span>
<span class='add'>+                            switch (presence_type)</span>
<span class='add'>+                            {</span>
<span class='add'>+                                case (RESOURCE_ONLINE):</span>
<span class='add'>+                                    accounts_set_priority_online(account_name, intval);</span>
<span class='add'>+                                    break;</span>
<span class='add'>+                                case (RESOURCE_CHAT):</span>
<span class='add'>+                                    accounts_set_priority_chat(account_name, intval);</span>
<span class='add'>+                                    break;</span>
<span class='add'>+                                case (RESOURCE_AWAY):</span>
<span class='add'>+                                    accounts_set_priority_away(account_name, intval);</span>
<span class='add'>+                                    break;</span>
<span class='add'>+                                case (RESOURCE_XA):</span>
<span class='add'>+                                    accounts_set_priority_xa(account_name, intval);</span>
<span class='add'>+                                    break;</span>
<span class='add'>+                                case (RESOURCE_DND):</span>
<span class='add'>+                                    accounts_set_priority_dnd(account_name, intval);</span>
<span class='add'>+                                    break;</span>
<span class='add'>+                            }</span>
<span class='add'>+                            jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+                            resource_presence_t last_presence = accounts_get_last_presence(jabber_get_account_name());</span>
<span class='add'>+                            if (conn_status == JABBER_CONNECTED &amp;&amp; presence_type == last_presence) {</span>
<span class='add'>+                                presence_update(last_presence, jabber_get_presence_message(), 0);</span>
<span class='add'>+                            }</span>
<span class='add'>+                            cons_show("Updated %s priority for account %s: %s", property, account_name, value);</span>
<span class='add'>+                            cons_show("");</span>
<span class='add'>+                        }</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("Invalid property: %s", property);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(command, "clear") == 0) {</span>
<span class='add'>+        if (g_strv_length(args) != 3) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            char *account_name = args[1];</span>
<span class='add'>+            char *property = args[2];</span>
<span class='add'>+</span>
<span class='add'>+            if (!accounts_account_exists(account_name)) {</span>
<span class='add'>+                cons_show("Account %s doesn't exist", account_name);</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                if (strcmp(property, "password") == 0) {</span>
<span class='add'>+                    accounts_clear_password(account_name);</span>
<span class='add'>+                    cons_show("Removed password for account %s", account_name);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("Invalid property: %s", property);</span>
<span class='add'>+                    cons_show("");</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_sub(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are currently not connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    char *subcmd, *jid;</span>
<span class='add'>+    subcmd = args[0];</span>
<span class='add'>+    jid = args[1];</span>
<span class='add'>+</span>
<span class='add'>+    if (subcmd == NULL) {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(subcmd, "sent") == 0) {</span>
<span class='add'>+        cons_show_sent_subs();</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(subcmd, "received") == 0) {</span>
<span class='add'>+        cons_show_received_subs();</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if ((win_type != WIN_CHAT) &amp;&amp; (jid == NULL)) {</span>
<span class='add'>+        cons_show("You must specify a contact.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (jid == NULL) {</span>
<span class='add'>+        jid = ui_current_recipient();</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    Jid *jidp = jid_create(jid);</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(subcmd, "allow") == 0) {</span>
<span class='add'>+        presence_subscription(jidp-&gt;barejid, PRESENCE_SUBSCRIBED);</span>
<span class='add'>+        cons_show("Accepted subscription for %s", jidp-&gt;barejid);</span>
<span class='add'>+        log_info("Accepted subscription for %s", jidp-&gt;barejid);</span>
<span class='add'>+    } else if (strcmp(subcmd, "deny") == 0) {</span>
<span class='add'>+        presence_subscription(jidp-&gt;barejid, PRESENCE_UNSUBSCRIBED);</span>
<span class='add'>+        cons_show("Deleted/denied subscription for %s", jidp-&gt;barejid);</span>
<span class='add'>+        log_info("Deleted/denied subscription for %s", jidp-&gt;barejid);</span>
<span class='add'>+    } else if (strcmp(subcmd, "request") == 0) {</span>
<span class='add'>+        presence_subscription(jidp-&gt;barejid, PRESENCE_SUBSCRIBE);</span>
<span class='add'>+        cons_show("Sent subscription request to %s.", jidp-&gt;barejid);</span>
<span class='add'>+        log_info("Sent subscription request to %s.", jidp-&gt;barejid);</span>
<span class='add'>+    } else if (strcmp(subcmd, "show") == 0) {</span>
<span class='add'>+        PContact contact = roster_get_contact(jidp-&gt;barejid);</span>
<span class='add'>+        if ((contact == NULL) || (p_contact_subscription(contact) == NULL)) {</span>
<span class='add'>+            if (win_type == WIN_CHAT) {</span>
<span class='add'>+                ui_current_print_line("No subscription information for %s.", jidp-&gt;barejid);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("No subscription information for %s.", jidp-&gt;barejid);</span>
<span class='add'>+            }</span>
<span class='add'>+        } else {</span>
<span class='add'>+            if (win_type == WIN_CHAT) {</span>
<span class='add'>+                if (p_contact_pending_out(contact)) {</span>
<span class='add'>+                    ui_current_print_line("%s subscription status: %s, request pending.",</span>
<span class='add'>+                        jidp-&gt;barejid, p_contact_subscription(contact));</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    ui_current_print_line("%s subscription status: %s.", jidp-&gt;barejid,</span>
<span class='add'>+                        p_contact_subscription(contact));</span>
<span class='add'>+                }</span>
<span class='add'>+            } else {</span>
<span class='add'>+                if (p_contact_pending_out(contact)) {</span>
<span class='add'>+                    cons_show("%s subscription status: %s, request pending.",</span>
<span class='add'>+                        jidp-&gt;barejid, p_contact_subscription(contact));</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("%s subscription status: %s.", jidp-&gt;barejid,</span>
<span class='add'>+                        p_contact_subscription(contact));</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    jid_destroy(jidp);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_disconnect(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    if (jabber_get_connection_status() == JABBER_CONNECTED) {</span>
<span class='add'>+        char *jid = strdup(jabber_get_fulljid());</span>
<span class='add'>+        prof_handle_disconnect(jid);</span>
<span class='add'>+        free(jid);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_quit(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    log_info("Profanity is shutting down...");</span>
<span class='add'>+    exit(0);</span>
<span class='add'>+    return FALSE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_wins(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    if (args[0] == NULL) {</span>
<span class='add'>+        cons_show_wins();</span>
<span class='add'>+    } else if (strcmp(args[0], "tidy") == 0) {</span>
<span class='add'>+        ui_tidy_wins();</span>
<span class='add'>+    } else if (strcmp(args[0], "prune") == 0) {</span>
<span class='add'>+        ui_prune_wins();</span>
<span class='add'>+    }</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_win(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    int num = atoi(args[0]);</span>
<span class='add'>+    if (ui_win_exists(num)) {</span>
<span class='add'>+        ui_switch_win(num);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Window %d does not exist.", num);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_help(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    int num_args = g_strv_length(args);</span>
<span class='add'>+    if (num_args == 0) {</span>
<span class='add'>+        cons_help();</span>
<span class='add'>+    } else if (strcmp(args[0], "commands") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show("All commands");</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+</span>
<span class='add'>+        GList *ordered_commands = NULL;</span>
<span class='add'>+        GHashTableIter iter;</span>
<span class='add'>+        gpointer key;</span>
<span class='add'>+        gpointer value;</span>
<span class='add'>+</span>
<span class='add'>+        g_hash_table_iter_init(&amp;iter, commands);</span>
<span class='add'>+        while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='add'>+            ordered_commands = g_list_insert_sorted(ordered_commands, value, (GCompareFunc)_compare_commands);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        GList *curr = ordered_commands;</span>
<span class='add'>+        while (curr != NULL) {</span>
<span class='add'>+            Command *cmd = curr-&gt;data;</span>
<span class='add'>+            cons_show("%-12s: %s", cmd-&gt;cmd, cmd-&gt;help.short_help);</span>
<span class='add'>+            curr = g_list_next(curr);</span>
<span class='add'>+        }</span>
<span class='add'>+        g_list_free(ordered_commands);</span>
<span class='add'>+        g_list_free(curr);</span>
<span class='add'>+</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show("Use /help [command] without the leading slash, for help on a specific command");</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "basic") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/about", "/clear", "/close", "/connect",</span>
<span class='add'>+            "/disconnect", "/help", "/msg", "/join", "/quit", "/vercheck",</span>
<span class='add'>+            "/wins" };</span>
<span class='add'>+        _cmd_show_filtered_help("Basic commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "chatting") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/chlog", "/duck", "/gone", "/history",</span>
<span class='add'>+            "/info", "/intype", "/msg", "/notify", "/outtype", "/status",</span>
<span class='add'>+            "/close", "/clear", "/tiny" };</span>
<span class='add'>+        _cmd_show_filtered_help("Chat commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "groupchat") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/close", "/clear", "/decline", "/grlog",</span>
<span class='add'>+            "/invite", "/invites", "/join", "/leave", "/notify", "/msg",</span>
<span class='add'>+            "/rooms", "/tiny", "/who", "/nick" };</span>
<span class='add'>+        _cmd_show_filtered_help("Groupchat commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "presence") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/autoaway", "/away", "/chat", "/dnd",</span>
<span class='add'>+            "/online", "/priority", "/account", "/status", "/statuses", "/who",</span>
<span class='add'>+            "/xa" };</span>
<span class='add'>+        _cmd_show_filtered_help("Presence commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "contacts") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/group", "/roster", "/sub", "/who" };</span>
<span class='add'>+        _cmd_show_filtered_help("Roster commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "service") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/caps", "/disco", "/info", "/software", "/rooms" };</span>
<span class='add'>+        _cmd_show_filtered_help("Service discovery commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "settings") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/account", "/autoaway", "/autoping", "/autoconnect", "/beep",</span>
<span class='add'>+            "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype",</span>
<span class='add'>+            "/log", "/mouse", "/notify", "/outtype", "/prefs", "/priority",</span>
<span class='add'>+            "/reconnect", "/roster", "/splash", "/states", "/statuses", "/theme",</span>
<span class='add'>+            "/titlebar", "/vercheck" };</span>
<span class='add'>+        _cmd_show_filtered_help("Settings commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "other") == 0) {</span>
<span class='add'>+        gchar *filter[] = { "/duck", "/vercheck" };</span>
<span class='add'>+        _cmd_show_filtered_help("Other commands", filter, ARRAY_SIZE(filter));</span>
<span class='add'>+</span>
<span class='add'>+    } else if (strcmp(args[0], "navigation") == 0) {</span>
<span class='add'>+        cons_navigation_help();</span>
<span class='add'>+    } else {</span>
<span class='add'>+        char *cmd = args[0];</span>
<span class='add'>+        char cmd_with_slash[1 + strlen(cmd) + 1];</span>
<span class='add'>+        sprintf(cmd_with_slash, "/%s", cmd);</span>
<span class='add'>+</span>
<span class='add'>+        const gchar **help_text = NULL;</span>
<span class='add'>+        Command *command = g_hash_table_lookup(commands, cmd_with_slash);</span>
<span class='add'>+</span>
<span class='add'>+        if (command != NULL) {</span>
<span class='add'>+            help_text = command-&gt;help.long_help;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+</span>
<span class='add'>+        if (help_text != NULL) {</span>
<span class='add'>+            int i;</span>
<span class='add'>+            for (i = 0; help_text[i] != NULL; i++) {</span>
<span class='add'>+                cons_show(help_text[i]);</span>
<span class='add'>+            }</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("No such command.");</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_about(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    cons_show("");</span>
<span class='add'>+    cons_about();</span>
<span class='add'>+    if (ui_current_win_type() != WIN_CONSOLE) {</span>
<span class='add'>+        status_bar_new(1);</span>
<span class='add'>+    }</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_prefs(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    if (args[0] == NULL) {</span>
<span class='add'>+        cons_prefs();</span>
<span class='add'>+        cons_show("Use the /account command for preferences for individual accounts.");</span>
<span class='add'>+    } else if (strcmp(args[0], "ui") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show_ui_prefs();</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    } else if (strcmp(args[0], "desktop") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show_desktop_prefs();</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    } else if (strcmp(args[0], "chat") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show_chat_prefs();</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    } else if (strcmp(args[0], "log") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show_log_prefs();</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    } else if (strcmp(args[0], "conn") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show_connection_prefs();</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    } else if (strcmp(args[0], "presence") == 0) {</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+        cons_show_presence_prefs();</span>
<span class='add'>+        cons_show("");</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_theme(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    // list themes</span>
<span class='add'>+    if (strcmp(args[0], "list") == 0) {</span>
<span class='add'>+        GSList *themes = theme_list();</span>
<span class='add'>+        cons_show_themes(themes);</span>
<span class='add'>+        g_slist_free_full(themes, g_free);</span>
<span class='add'>+</span>
<span class='add'>+    // load a theme</span>
<span class='add'>+    } else if (strcmp(args[0], "set") == 0) {</span>
<span class='add'>+        if (args[1] == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        } else if (theme_load(args[1])) {</span>
<span class='add'>+            ui_load_colours();</span>
<span class='add'>+            prefs_set_string(PREF_THEME, args[1]);</span>
<span class='add'>+            cons_show("Loaded theme: %s", args[1]);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Couldn't find theme: %s", args[1]);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_who(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+    } else {</span>
<span class='add'>+        char *presence = args[0];</span>
<span class='add'>+        char *group = NULL;</span>
<span class='add'>+        if ((g_strv_length(args) == 2) &amp;&amp; (args[1] != NULL)) {</span>
<span class='add'>+            group = args[1];</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        // bad arg</span>
<span class='add'>+        if ((presence != NULL)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "online") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "available") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "unavailable") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "offline") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "away") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "chat") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "xa") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "dnd") != 0)</span>
<span class='add'>+                &amp;&amp; (strcmp(presence, "any") != 0)) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+</span>
<span class='add'>+        // valid arg</span>
<span class='add'>+        } else {</span>
<span class='add'>+            if (win_type == WIN_MUC) {</span>
<span class='add'>+                if (group != NULL) {</span>
<span class='add'>+                    cons_show("The group argument is not valid when in a chat room.");</span>
<span class='add'>+                    return TRUE;</span>
<span class='add'>+                }</span>
<span class='add'>+</span>
<span class='add'>+                char *room = ui_current_recipient();</span>
<span class='add'>+                GList *list = muc_get_roster(room);</span>
<span class='add'>+</span>
<span class='add'>+                // no arg, show all contacts</span>
<span class='add'>+                if ((presence == NULL) || (g_strcmp0(presence, "any") == 0)) {</span>
<span class='add'>+                    ui_room_roster(room, list, NULL);</span>
<span class='add'>+</span>
<span class='add'>+                // available</span>
<span class='add'>+                } else if (strcmp("available", presence) == 0) {</span>
<span class='add'>+                    GList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (p_contact_is_available(contact)) {</span>
<span class='add'>+                            filtered = g_list_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_list_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    ui_room_roster(room, filtered, "available");</span>
<span class='add'>+</span>
<span class='add'>+                // unavailable</span>
<span class='add'>+                } else if (strcmp("unavailable", presence) == 0) {</span>
<span class='add'>+                    GList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (!p_contact_is_available(contact)) {</span>
<span class='add'>+                            filtered = g_list_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_list_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    ui_room_roster(room, filtered, "unavailable");</span>
<span class='add'>+</span>
<span class='add'>+                // online, available resources</span>
<span class='add'>+                } else if (strcmp("online", presence) == 0) {</span>
<span class='add'>+                    GList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (p_contact_has_available_resource(contact)) {</span>
<span class='add'>+                            filtered = g_list_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_list_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    ui_room_roster(room, filtered, "online");</span>
<span class='add'>+</span>
<span class='add'>+                // offline, no available resources</span>
<span class='add'>+                } else if (strcmp("offline", presence) == 0) {</span>
<span class='add'>+                    GList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (!p_contact_has_available_resource(contact)) {</span>
<span class='add'>+                            filtered = g_list_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_list_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    ui_room_roster(room, filtered, "offline");</span>
<span class='add'>+</span>
<span class='add'>+                // show specific status</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    GList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (strcmp(p_contact_presence(contact), presence) == 0) {</span>
<span class='add'>+                            filtered = g_list_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_list_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    ui_room_roster(room, filtered, presence);</span>
<span class='add'>+                }</span>
<span class='add'>+</span>
<span class='add'>+            // not in groupchat window</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("");</span>
<span class='add'>+                GSList *list = NULL;</span>
<span class='add'>+                if (group != NULL) {</span>
<span class='add'>+                    list = roster_get_group(group);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    list = roster_get_contacts();</span>
<span class='add'>+                }</span>
<span class='add'>+</span>
<span class='add'>+                // no arg, show all contacts</span>
<span class='add'>+                if ((presence == NULL) || (g_strcmp0(presence, "any") == 0)) {</span>
<span class='add'>+                    if (group != NULL) {</span>
<span class='add'>+                        cons_show("%s:", group);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        cons_show("All contacts:");</span>
<span class='add'>+                    }</span>
<span class='add'>+                    cons_show_contacts(list);</span>
<span class='add'>+</span>
<span class='add'>+                // available</span>
<span class='add'>+                } else if (strcmp("available", presence) == 0) {</span>
<span class='add'>+                    if (group != NULL) {</span>
<span class='add'>+                        cons_show("%s (%s):", group, presence);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        cons_show("Contacts (%s):", presence);</span>
<span class='add'>+                    }</span>
<span class='add'>+                    GSList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (p_contact_is_available(contact)) {</span>
<span class='add'>+                            filtered = g_slist_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_slist_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    cons_show_contacts(filtered);</span>
<span class='add'>+</span>
<span class='add'>+                // unavailable</span>
<span class='add'>+                } else if (strcmp("unavailable", presence) == 0) {</span>
<span class='add'>+                    if (group != NULL) {</span>
<span class='add'>+                        cons_show("%s (%s):", group, presence);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        cons_show("Contacts (%s):", presence);</span>
<span class='add'>+                    }</span>
<span class='add'>+                    GSList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (!p_contact_is_available(contact)) {</span>
<span class='add'>+                            filtered = g_slist_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_slist_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    cons_show_contacts(filtered);</span>
<span class='add'>+</span>
<span class='add'>+                // online, available resources</span>
<span class='add'>+                } else if (strcmp("online", presence) == 0) {</span>
<span class='add'>+                    if (group != NULL) {</span>
<span class='add'>+                        cons_show("%s (%s):", group, presence);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        cons_show("Contacts (%s):", presence);</span>
<span class='add'>+                    }</span>
<span class='add'>+                    GSList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (p_contact_has_available_resource(contact)) {</span>
<span class='add'>+                            filtered = g_slist_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_slist_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    cons_show_contacts(filtered);</span>
<span class='add'>+</span>
<span class='add'>+                // offline, no available resources</span>
<span class='add'>+                } else if (strcmp("offline", presence) == 0) {</span>
<span class='add'>+                    if (group != NULL) {</span>
<span class='add'>+                        cons_show("%s (%s):", group, presence);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        cons_show("Contacts (%s):", presence);</span>
<span class='add'>+                    }</span>
<span class='add'>+                    GSList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (!p_contact_has_available_resource(contact)) {</span>
<span class='add'>+                            filtered = g_slist_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_slist_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    cons_show_contacts(filtered);</span>
<span class='add'>+</span>
<span class='add'>+                // show specific status</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    if (group != NULL) {</span>
<span class='add'>+                        cons_show("%s (%s):", group, presence);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        cons_show("Contacts (%s):", presence);</span>
<span class='add'>+                    }</span>
<span class='add'>+                    GSList *filtered = NULL;</span>
<span class='add'>+</span>
<span class='add'>+                    while (list != NULL) {</span>
<span class='add'>+                        PContact contact = list-&gt;data;</span>
<span class='add'>+                        if (strcmp(p_contact_presence(contact), presence) == 0) {</span>
<span class='add'>+                            filtered = g_slist_append(filtered, contact);</span>
<span class='add'>+                        }</span>
<span class='add'>+                        list = g_slist_next(list);</span>
<span class='add'>+                    }</span>
<span class='add'>+</span>
<span class='add'>+                    cons_show_contacts(filtered);</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (win_type != WIN_CONSOLE &amp;&amp; win_type != WIN_MUC) {</span>
<span class='add'>+        status_bar_new(1);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_msg(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *usr = args[0];</span>
<span class='add'>+    char *msg = args[1];</span>
<span class='add'>+</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (win_type == WIN_MUC) {</span>
<span class='add'>+        char *room_name = ui_current_recipient();</span>
<span class='add'>+        if (muc_nick_in_roster(room_name, usr)) {</span>
<span class='add'>+            GString *full_jid = g_string_new(room_name);</span>
<span class='add'>+            g_string_append(full_jid, "/");</span>
<span class='add'>+            g_string_append(full_jid, usr);</span>
<span class='add'>+</span>
<span class='add'>+            if (msg != NULL) {</span>
<span class='add'>+                message_send(msg, full_jid-&gt;str);</span>
<span class='add'>+                ui_outgoing_msg("me", full_jid-&gt;str, msg);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                ui_new_chat_win(full_jid-&gt;str);</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            g_string_free(full_jid, TRUE);</span>
<span class='add'>+</span>
<span class='add'>+        } else {</span>
<span class='add'>+            ui_current_print_line("No such participant \"%s\" in room.", usr);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+</span>
<span class='add'>+    } else {</span>
<span class='add'>+        char *usr_jid = roster_barejid_from_name(usr);</span>
<span class='add'>+        if (usr_jid == NULL) {</span>
<span class='add'>+            usr_jid = usr;</span>
<span class='add'>+        }</span>
<span class='add'>+        if (msg != NULL) {</span>
<span class='add'>+            message_send(msg, usr_jid);</span>
<span class='add'>+            ui_outgoing_msg("me", usr_jid, msg);</span>
<span class='add'>+</span>
<span class='add'>+            if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) &amp;&amp; prefs_get_boolean(PREF_CHLOG)) {</span>
<span class='add'>+                const char *jid = jabber_get_fulljid();</span>
<span class='add'>+                Jid *jidp = jid_create(jid);</span>
<span class='add'>+                chat_log_chat(jidp-&gt;barejid, usr_jid, msg, PROF_OUT_LOG, NULL);</span>
<span class='add'>+                jid_destroy(jidp);</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        } else {</span>
<span class='add'>+            const char * jid = NULL;</span>
<span class='add'>+</span>
<span class='add'>+            if (roster_barejid_from_name(usr_jid) != NULL) {</span>
<span class='add'>+                jid = roster_barejid_from_name(usr_jid);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                jid = usr_jid;</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            if (prefs_get_boolean(PREF_STATES)) {</span>
<span class='add'>+                if (!chat_session_exists(jid)) {</span>
<span class='add'>+                    chat_session_start(jid, TRUE);</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            ui_new_chat_win(usr_jid);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_group(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // list all groups</span>
<span class='add'>+    if (args[0] == NULL) {</span>
<span class='add'>+        GSList *groups = roster_get_groups();</span>
<span class='add'>+        GSList *curr = groups;</span>
<span class='add'>+        if (curr != NULL) {</span>
<span class='add'>+            cons_show("Groups:");</span>
<span class='add'>+            while (curr != NULL) {</span>
<span class='add'>+                cons_show("  %s", curr-&gt;data);</span>
<span class='add'>+                curr = g_slist_next(curr);</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            g_slist_free_full(groups, g_free);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("No groups.");</span>
<span class='add'>+        }</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // show contacts in group</span>
<span class='add'>+    if (strcmp(args[0], "show") == 0) {</span>
<span class='add'>+        char *group = args[1];</span>
<span class='add'>+        if (group == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        GSList *list = roster_get_group(group);</span>
<span class='add'>+        cons_show_roster_group(group, list);</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // add contact to group</span>
<span class='add'>+    if (strcmp(args[0], "add") == 0) {</span>
<span class='add'>+        char *group = args[1];</span>
<span class='add'>+        char *contact = args[2];</span>
<span class='add'>+</span>
<span class='add'>+        if ((group == NULL) || (contact == NULL)) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        char *barejid = roster_barejid_from_name(contact);</span>
<span class='add'>+        if (barejid == NULL) {</span>
<span class='add'>+            barejid = contact;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        PContact pcontact = roster_get_contact(barejid);</span>
<span class='add'>+        if (pcontact == NULL) {</span>
<span class='add'>+            cons_show("Contact not found in roster: %s", barejid);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        roster_add_to_group(group, barejid);</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // remove contact from group</span>
<span class='add'>+    if (strcmp(args[0], "remove") == 0) {</span>
<span class='add'>+        char *group = args[1];</span>
<span class='add'>+        char *contact = args[2];</span>
<span class='add'>+</span>
<span class='add'>+        if ((group == NULL) || (contact == NULL)) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        char *barejid = roster_barejid_from_name(contact);</span>
<span class='add'>+        if (barejid == NULL) {</span>
<span class='add'>+            barejid = contact;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        PContact pcontact = roster_get_contact(barejid);</span>
<span class='add'>+        if (pcontact == NULL) {</span>
<span class='add'>+            cons_show("Contact not found in roster: %s", barejid);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        roster_remove_from_group(group, barejid);</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_roster(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // show roster</span>
<span class='add'>+    if (args[0] == NULL) {</span>
<span class='add'>+        GSList *list = roster_get_contacts();</span>
<span class='add'>+        cons_show_roster(list);</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // add contact</span>
<span class='add'>+    if (strcmp(args[0], "add") == 0) {</span>
<span class='add'>+</span>
<span class='add'>+        if (args[1] == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        char *jid = args[1];</span>
<span class='add'>+        char *name = args[2];</span>
<span class='add'>+</span>
<span class='add'>+        roster_add_new(jid, name);</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // remove contact</span>
<span class='add'>+    if (strcmp(args[0], "remove") == 0) {</span>
<span class='add'>+</span>
<span class='add'>+        if (args[1] == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        char *jid = args[1];</span>
<span class='add'>+</span>
<span class='add'>+        roster_send_remove(jid);</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // change nickname</span>
<span class='add'>+    if (strcmp(args[0], "nick") == 0) {</span>
<span class='add'>+</span>
<span class='add'>+        if (args[1] == NULL) {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        char *jid = args[1];</span>
<span class='add'>+        char *name = args[2];</span>
<span class='add'>+</span>
<span class='add'>+        // contact does not exist</span>
<span class='add'>+        PContact contact = roster_get_contact(jid);</span>
<span class='add'>+        if (contact == NULL) {</span>
<span class='add'>+            cons_show("Contact not found in roster: %s", jid);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        roster_change_name(jid, name);</span>
<span class='add'>+</span>
<span class='add'>+        if (name == NULL) {</span>
<span class='add'>+            cons_show("Nickname for %s removed.", jid);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Nickname for %s set to: %s.", jid, name);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_duck(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *query = args[0];</span>
<span class='add'>+</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // if no duck win open, create it and send a help command</span>
<span class='add'>+    if (!ui_duck_exists()) {</span>
<span class='add'>+        ui_create_duck_win();</span>
<span class='add'>+</span>
<span class='add'>+        if (query != NULL) {</span>
<span class='add'>+            message_send_duck(query);</span>
<span class='add'>+            ui_duck(query);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+    // window exists, send query</span>
<span class='add'>+    } else {</span>
<span class='add'>+        ui_open_duck_win();</span>
<span class='add'>+</span>
<span class='add'>+        if (query != NULL) {</span>
<span class='add'>+            message_send_duck(query);</span>
<span class='add'>+            ui_duck(query);</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_status(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *usr = args[0];</span>
<span class='add'>+    char *usr_jid = NULL;</span>
<span class='add'>+</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    switch (win_type)</span>
<span class='add'>+    {</span>
<span class='add'>+        case WIN_MUC:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                ui_status_room(usr);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                ui_current_print_line("You must specify a nickname.");</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CHAT:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                ui_current_print_line("No parameter required when in chat.");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                ui_status();</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_PRIVATE:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                ui_current_print_line("No parameter required when in chat.");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                ui_status_private();</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CONSOLE:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                usr_jid = roster_barejid_from_name(usr);</span>
<span class='add'>+                if (usr_jid == NULL) {</span>
<span class='add'>+                    usr_jid = usr;</span>
<span class='add'>+                }</span>
<span class='add'>+                cons_show_status(usr_jid);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        default:</span>
<span class='add'>+            break;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_info(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *usr = args[0];</span>
<span class='add'>+    char *usr_jid = NULL;</span>
<span class='add'>+</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+    PContact pcontact = NULL;</span>
<span class='add'>+    char *recipient;</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    recipient = ui_current_recipient();</span>
<span class='add'>+</span>
<span class='add'>+    switch (win_type)</span>
<span class='add'>+    {</span>
<span class='add'>+        case WIN_MUC:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                pcontact = muc_get_participant(recipient, usr);</span>
<span class='add'>+                if (pcontact != NULL) {</span>
<span class='add'>+                    cons_show_info(pcontact);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("No such participant \"%s\" in room.", usr);</span>
<span class='add'>+                }</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("No nickname supplied to /info in chat room.");</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CHAT:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                cons_show("No parameter required for /info in chat.");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                pcontact = roster_get_contact(recipient);</span>
<span class='add'>+                if (pcontact != NULL) {</span>
<span class='add'>+                    cons_show_info(pcontact);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("No such contact \"%s\" in roster.", recipient);</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_PRIVATE:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                ui_current_print_line("No parameter required when in chat.");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                Jid *jid = jid_create(recipient);</span>
<span class='add'>+                pcontact = muc_get_participant(jid-&gt;barejid, jid-&gt;resourcepart);</span>
<span class='add'>+                if (pcontact != NULL) {</span>
<span class='add'>+                    cons_show_info(pcontact);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("No such participant \"%s\" in room.", jid-&gt;resourcepart);</span>
<span class='add'>+                }</span>
<span class='add'>+                jid_destroy(jid);</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CONSOLE:</span>
<span class='add'>+            if (usr != NULL) {</span>
<span class='add'>+                usr_jid = roster_barejid_from_name(usr);</span>
<span class='add'>+                if (usr_jid == NULL) {</span>
<span class='add'>+                    usr_jid = usr;</span>
<span class='add'>+                }</span>
<span class='add'>+                pcontact = roster_get_contact(usr_jid);</span>
<span class='add'>+                if (pcontact != NULL) {</span>
<span class='add'>+                    cons_show_info(pcontact);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("No such contact \"%s\" in roster.", usr);</span>
<span class='add'>+                }</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        default:</span>
<span class='add'>+            break;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_caps(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+    PContact pcontact = NULL;</span>
<span class='add'>+    char *recipient;</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    switch (win_type)</span>
<span class='add'>+    {</span>
<span class='add'>+        case WIN_MUC:</span>
<span class='add'>+            if (args[0] != NULL) {</span>
<span class='add'>+                recipient = ui_current_recipient();</span>
<span class='add'>+                pcontact = muc_get_participant(recipient, args[0]);</span>
<span class='add'>+                if (pcontact != NULL) {</span>
<span class='add'>+                    Resource *resource = p_contact_get_resource(pcontact, args[0]);</span>
<span class='add'>+                    cons_show_caps(args[0], resource);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("No such participant \"%s\" in room.", args[0]);</span>
<span class='add'>+                }</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("No nickname supplied to /caps in chat room.");</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CHAT:</span>
<span class='add'>+        case WIN_CONSOLE:</span>
<span class='add'>+            if (args[0] != NULL) {</span>
<span class='add'>+                Jid *jid = jid_create(args[0]);</span>
<span class='add'>+</span>
<span class='add'>+                if (jid-&gt;fulljid == NULL) {</span>
<span class='add'>+                    cons_show("You must provide a full jid to the /caps command.");</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    pcontact = roster_get_contact(jid-&gt;barejid);</span>
<span class='add'>+                    if (pcontact == NULL) {</span>
<span class='add'>+                        cons_show("Contact not found in roster: %s", jid-&gt;barejid);</span>
<span class='add'>+                    } else {</span>
<span class='add'>+                        Resource *resource = p_contact_get_resource(pcontact, jid-&gt;resourcepart);</span>
<span class='add'>+                        if (resource == NULL) {</span>
<span class='add'>+                            cons_show("Could not find resource %s, for contact %s", jid-&gt;barejid, jid-&gt;resourcepart);</span>
<span class='add'>+                        } else {</span>
<span class='add'>+                            cons_show_caps(jid-&gt;fulljid, resource);</span>
<span class='add'>+                        }</span>
<span class='add'>+                    }</span>
<span class='add'>+                }</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("You must provide a jid to the /caps command.");</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_PRIVATE:</span>
<span class='add'>+            if (args[0] != NULL) {</span>
<span class='add'>+                cons_show("No parameter needed to /caps when in private chat.");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                recipient = ui_current_recipient();</span>
<span class='add'>+                Jid *jid = jid_create(recipient);</span>
<span class='add'>+                if (jid) {</span>
<span class='add'>+                    pcontact = muc_get_participant(jid-&gt;barejid, jid-&gt;resourcepart);</span>
<span class='add'>+                    Resource *resource = p_contact_get_resource(pcontact, jid-&gt;resourcepart);</span>
<span class='add'>+                    cons_show_caps(jid-&gt;resourcepart, resource);</span>
<span class='add'>+                    jid_destroy(jid);</span>
<span class='add'>+                }</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        default:</span>
<span class='add'>+            break;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_software(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+    PContact pcontact = NULL;</span>
<span class='add'>+    char *recipient;</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    switch (win_type)</span>
<span class='add'>+    {</span>
<span class='add'>+        case WIN_MUC:</span>
<span class='add'>+            if (args[0] != NULL) {</span>
<span class='add'>+                recipient = ui_current_recipient();</span>
<span class='add'>+                pcontact = muc_get_participant(recipient, args[0]);</span>
<span class='add'>+                if (pcontact != NULL) {</span>
<span class='add'>+                    Jid *jid = jid_create_from_bare_and_resource(recipient, args[0]);</span>
<span class='add'>+                    iq_send_software_version(jid-&gt;fulljid);</span>
<span class='add'>+                    jid_destroy(jid);</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    cons_show("No such participant \"%s\" in room.", args[0]);</span>
<span class='add'>+                }</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("No nickname supplied to /software in chat room.");</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CHAT:</span>
<span class='add'>+        case WIN_CONSOLE:</span>
<span class='add'>+            if (args[0] != NULL) {</span>
<span class='add'>+                Jid *jid = jid_create(args[0]);</span>
<span class='add'>+</span>
<span class='add'>+                if (jid == NULL || jid-&gt;fulljid == NULL) {</span>
<span class='add'>+                    cons_show("You must provide a full jid to the /software command.");</span>
<span class='add'>+                } else {</span>
<span class='add'>+                    iq_send_software_version(jid-&gt;fulljid);</span>
<span class='add'>+                }</span>
<span class='add'>+                jid_destroy(jid);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("You must provide a jid to the /software command.");</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_PRIVATE:</span>
<span class='add'>+            if (args[0] != NULL) {</span>
<span class='add'>+                cons_show("No parameter needed to /software when in private chat.");</span>
<span class='add'>+            } else {</span>
<span class='add'>+                recipient = ui_current_recipient();</span>
<span class='add'>+                iq_send_software_version(recipient);</span>
<span class='add'>+            }</span>
<span class='add'>+            break;</span>
<span class='add'>+        default:</span>
<span class='add'>+            break;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_join(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    Jid *room_arg = jid_create(args[0]);</span>
<span class='add'>+    if (room_arg == NULL) {</span>
<span class='add'>+        cons_show_error("Specified room has incorrect format");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    int num_args = g_strv_length(args);</span>
<span class='add'>+    char *room = NULL;</span>
<span class='add'>+    char *nick = NULL;</span>
<span class='add'>+    GString *room_str = g_string_new("");</span>
<span class='add'>+    Jid *my_jid = jid_create(jabber_get_fulljid());</span>
<span class='add'>+</span>
<span class='add'>+    // full room jid supplied (room@server)</span>
<span class='add'>+    if (room_arg-&gt;localpart != NULL) {</span>
<span class='add'>+        room = args[0];</span>
<span class='add'>+</span>
<span class='add'>+    // server not supplied (room), use account preference</span>
<span class='add'>+    } else {</span>
<span class='add'>+        g_string_append(room_str, args[0]);</span>
<span class='add'>+        g_string_append(room_str, "@");</span>
<span class='add'>+        g_string_append(room_str, account-&gt;muc_service);</span>
<span class='add'>+        room = room_str-&gt;str;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // nick supplied</span>
<span class='add'>+    if (num_args == 2) {</span>
<span class='add'>+        nick = args[1];</span>
<span class='add'>+</span>
<span class='add'>+    // otherwise use account preference</span>
<span class='add'>+    } else {</span>
<span class='add'>+        nick = account-&gt;muc_nick;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    Jid *room_jid = jid_create_from_bare_and_resource(room, nick);</span>
<span class='add'>+</span>
<span class='add'>+    if (!muc_room_is_active(room_jid)) {</span>
<span class='add'>+        presence_join_room(room_jid);</span>
<span class='add'>+    }</span>
<span class='add'>+    ui_room_join(room_jid);</span>
<span class='add'>+    muc_remove_invite(room);</span>
<span class='add'>+</span>
<span class='add'>+    jid_destroy(room_arg);</span>
<span class='add'>+    jid_destroy(room_jid);</span>
<span class='add'>+    jid_destroy(my_jid);</span>
<span class='add'>+    g_string_free(room_str, TRUE);</span>
<span class='add'>+    accounts_free_account(account);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_invite(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *contact = args[0];</span>
<span class='add'>+    char *reason = args[1];</span>
<span class='add'>+    char *room = NULL;</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (ui_current_win_type() != WIN_MUC) {</span>
<span class='add'>+        cons_show("You must be in a chat room to send an invite.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    char *usr_jid = roster_barejid_from_name(contact);</span>
<span class='add'>+    if (usr_jid == NULL) {</span>
<span class='add'>+        usr_jid = contact;</span>
<span class='add'>+    }</span>
<span class='add'>+    room = ui_current_recipient();</span>
<span class='add'>+    message_send_invite(room, usr_jid, reason);</span>
<span class='add'>+    if (reason != NULL) {</span>
<span class='add'>+        cons_show("Room invite sent, contact: %s, room: %s, reason: \"%s\".",</span>
<span class='add'>+            contact, room, reason);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Room invite sent, contact: %s, room: %s.",</span>
<span class='add'>+            contact, room);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_invites(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    GSList *invites = muc_get_invites();</span>
<span class='add'>+    cons_show_room_invites(invites);</span>
<span class='add'>+    g_slist_free_full(invites, g_free);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_decline(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    if (!muc_invites_include(args[0])) {</span>
<span class='add'>+        cons_show("No such invite exists.");</span>
<span class='add'>+    } else {</span>
<span class='add'>+        muc_remove_invite(args[0]);</span>
<span class='add'>+        cons_show("Declined invite to %s.", args[0]);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_rooms(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (args[0] == NULL) {</span>
<span class='add'>+        ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='add'>+        iq_room_list_request(account-&gt;muc_service);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        iq_room_list_request(args[0]);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_bookmark(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    gchar *cmd = args[0];</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currenlty connect.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    /* TODO: /bookmark list room@server */</span>
<span class='add'>+</span>
<span class='add'>+    if (cmd == NULL || strcmp(cmd, "list") == 0) {</span>
<span class='add'>+        cons_show_bookmarks(bookmark_get_list());</span>
<span class='add'>+    } else {</span>
<span class='add'>+        gboolean autojoin = FALSE;</span>
<span class='add'>+        gchar *jid = NULL;</span>
<span class='add'>+        gchar *nick = NULL;</span>
<span class='add'>+        int idx = 1;</span>
<span class='add'>+</span>
<span class='add'>+        while (args[idx] != NULL) {</span>
<span class='add'>+            gchar *opt = args[idx];</span>
<span class='add'>+</span>
<span class='add'>+            if (strcmp(opt, "autojoin") == 0) {</span>
<span class='add'>+                autojoin = TRUE;</span>
<span class='add'>+            } else if (jid == NULL) {</span>
<span class='add'>+                jid = opt;</span>
<span class='add'>+            } else if (nick == NULL) {</span>
<span class='add'>+                nick = opt;</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("Usage: %s", help.usage);</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            ++idx;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        if (jid == NULL) {</span>
<span class='add'>+            win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+</span>
<span class='add'>+            if (win_type == WIN_MUC) {</span>
<span class='add'>+                jid = ui_current_recipient();</span>
<span class='add'>+                nick = muc_get_room_nick(jid);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                cons_show("Usage: %s", help.usage);</span>
<span class='add'>+                return TRUE;</span>
<span class='add'>+            }</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        if (strcmp(cmd, "add") == 0) {</span>
<span class='add'>+            bookmark_add(jid, nick, autojoin);</span>
<span class='add'>+        } else if (strcmp(cmd, "remove") == 0) {</span>
<span class='add'>+            bookmark_remove(jid, autojoin);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_disco(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currenlty connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    GString *jid = g_string_new("");</span>
<span class='add'>+    if (args[1] != NULL) {</span>
<span class='add'>+        jid = g_string_append(jid, args[1]);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        Jid *jidp = jid_create(jabber_get_fulljid());</span>
<span class='add'>+        jid = g_string_append(jid, jidp-&gt;domainpart);</span>
<span class='add'>+        jid_destroy(jidp);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (g_strcmp0(args[0], "info") == 0) {</span>
<span class='add'>+        iq_disco_info_request(jid-&gt;str);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        iq_disco_items_request(jid-&gt;str);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    g_string_free(jid, TRUE);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_nick(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+    if (ui_current_win_type() != WIN_MUC) {</span>
<span class='add'>+        cons_show("You can only change your nickname in a chat room window.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    char *room = ui_current_recipient();</span>
<span class='add'>+    char *nick = args[0];</span>
<span class='add'>+    presence_change_room_nick(room, nick);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_tiny(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *url = args[0];</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+</span>
<span class='add'>+    if (!tinyurl_valid(url)) {</span>
<span class='add'>+        GString *error = g_string_new("/tiny, badly formed URL: ");</span>
<span class='add'>+        g_string_append(error, url);</span>
<span class='add'>+        cons_show_error(error-&gt;str);</span>
<span class='add'>+        if (win_type != WIN_CONSOLE) {</span>
<span class='add'>+            ui_current_error_line(error-&gt;str);</span>
<span class='add'>+        }</span>
<span class='add'>+        g_string_free(error, TRUE);</span>
<span class='add'>+    } else if (win_type != WIN_CONSOLE) {</span>
<span class='add'>+        char *tiny = tinyurl_get(url);</span>
<span class='add'>+</span>
<span class='add'>+        if (tiny != NULL) {</span>
<span class='add'>+            if (win_type == WIN_CHAT) {</span>
<span class='add'>+                char *recipient = ui_current_recipient();</span>
<span class='add'>+                message_send(tiny, recipient);</span>
<span class='add'>+</span>
<span class='add'>+                if (prefs_get_boolean(PREF_CHLOG)) {</span>
<span class='add'>+                    const char *jid = jabber_get_fulljid();</span>
<span class='add'>+                    Jid *jidp = jid_create(jid);</span>
<span class='add'>+                    chat_log_chat(jidp-&gt;barejid, recipient, tiny, PROF_OUT_LOG, NULL);</span>
<span class='add'>+                    jid_destroy(jidp);</span>
<span class='add'>+                }</span>
<span class='add'>+</span>
<span class='add'>+                ui_outgoing_msg("me", recipient, tiny);</span>
<span class='add'>+            } else if (win_type == WIN_PRIVATE) {</span>
<span class='add'>+                char *recipient = ui_current_recipient();</span>
<span class='add'>+                message_send(tiny, recipient);</span>
<span class='add'>+                ui_outgoing_msg("me", recipient, tiny);</span>
<span class='add'>+            } else { // groupchat</span>
<span class='add'>+                char *recipient = ui_current_recipient();</span>
<span class='add'>+                message_send_groupchat(tiny, recipient);</span>
<span class='add'>+            }</span>
<span class='add'>+            free(tiny);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show_error("Couldn't get tinyurl.");</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("/tiny can only be used in chat windows");</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_clear(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    ui_clear_current();</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_close(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    int index = 0;</span>
<span class='add'>+    int count = 0;</span>
<span class='add'>+</span>
<span class='add'>+    if (args[0] == NULL) {</span>
<span class='add'>+        index = ui_current_win_index();</span>
<span class='add'>+    } else if (strcmp(args[0], "all") == 0) {</span>
<span class='add'>+        count = ui_close_all_wins();</span>
<span class='add'>+        if (count == 0) {</span>
<span class='add'>+            cons_show("No windows to close.");</span>
<span class='add'>+        } else if (count == 1) {</span>
<span class='add'>+            cons_show("Closed 1 window.");</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Closed %d windows.", count);</span>
<span class='add'>+        }</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    } else if (strcmp(args[0], "read") == 0) {</span>
<span class='add'>+        count = ui_close_read_wins();</span>
<span class='add'>+        if (count == 0) {</span>
<span class='add'>+            cons_show("No windows to close.");</span>
<span class='add'>+        } else if (count == 1) {</span>
<span class='add'>+            cons_show("Closed 1 window.");</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Closed %d windows.", count);</span>
<span class='add'>+        }</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    } else {</span>
<span class='add'>+        index = atoi(args[0]);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (index &lt; 0 || index == 10) {</span>
<span class='add'>+        cons_show("No such window exists.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (index == 1) {</span>
<span class='add'>+        cons_show("Cannot close console window.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (index == 0) {</span>
<span class='add'>+        index = 10;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (!ui_win_exists(index)) {</span>
<span class='add'>+        cons_show("Window is not open.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // handle leaving rooms, or chat</span>
<span class='add'>+    if (conn_status == JABBER_CONNECTED) {</span>
<span class='add'>+        ui_close_connected_win(index);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // close the window</span>
<span class='add'>+    ui_close_win(index);</span>
<span class='add'>+    cons_show("Closed window %d", index);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_leave(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+    win_type_t win_type = ui_current_win_type();</span>
<span class='add'>+    int index = ui_current_win_index();</span>
<span class='add'>+</span>
<span class='add'>+    if (win_type != WIN_MUC) {</span>
<span class='add'>+        cons_show("You can only use the /leave command in a chat room.");</span>
<span class='add'>+        cons_alert();</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // handle leaving rooms, or chat</span>
<span class='add'>+    if (conn_status == JABBER_CONNECTED) {</span>
<span class='add'>+        ui_close_connected_win(index);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // close the window</span>
<span class='add'>+    ui_close_win(index);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_beep(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    return _cmd_set_boolean_preference(args[0], help, "Sound", PREF_BEEP);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_states(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean result = _cmd_set_boolean_preference(args[0], help, "Sending chat states",</span>
<span class='add'>+        PREF_STATES);</span>
<span class='add'>+</span>
<span class='add'>+    // if disabled, disable outtype and gone</span>
<span class='add'>+    if (result == TRUE &amp;&amp; (strcmp(args[0], "off") == 0)) {</span>
<span class='add'>+        prefs_set_boolean(PREF_OUTTYPE, FALSE);</span>
<span class='add'>+        prefs_set_gone(0);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_titlebar(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    if (strcmp(args[0], "version") != 0) {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    } else {</span>
<span class='add'>+        return _cmd_set_boolean_preference(args[1], help,</span>
<span class='add'>+        "Show version in window title", PREF_TITLEBARVERSION);</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_outtype(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Sending typing notifications", PREF_OUTTYPE);</span>
<span class='add'>+</span>
<span class='add'>+    // if enabled, enable states</span>
<span class='add'>+    if (result == TRUE &amp;&amp; (strcmp(args[0], "on") == 0)) {</span>
<span class='add'>+        prefs_set_boolean(PREF_STATES, TRUE);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_gone(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *value = args[0];</span>
<span class='add'>+</span>
<span class='add'>+    gint period = atoi(value);</span>
<span class='add'>+    prefs_set_gone(period);</span>
<span class='add'>+    if (period == 0) {</span>
<span class='add'>+        cons_show("Automatic leaving conversations after period disabled.");</span>
<span class='add'>+    } else if (period == 1) {</span>
<span class='add'>+        cons_show("Leaving conversations after 1 minute of inactivity.");</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Leaving conversations after %d minutes of inactivity.", period);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // if enabled, enable states</span>
<span class='add'>+    if (period &gt; 0) {</span>
<span class='add'>+        prefs_set_boolean(PREF_STATES, TRUE);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_notify(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *kind = args[0];</span>
<span class='add'>+    char *value = args[1];</span>
<span class='add'>+</span>
<span class='add'>+    // bad kind</span>
<span class='add'>+    if ((strcmp(kind, "message") != 0) &amp;&amp; (strcmp(kind, "typing") != 0) &amp;&amp;</span>
<span class='add'>+            (strcmp(kind, "remind") != 0) &amp;&amp; (strcmp(kind, "invite") != 0) &amp;&amp;</span>
<span class='add'>+            (strcmp(kind, "sub") != 0)) {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+</span>
<span class='add'>+    // set message setting</span>
<span class='add'>+    } else if (strcmp(kind, "message") == 0) {</span>
<span class='add'>+        if (strcmp(value, "on") == 0) {</span>
<span class='add'>+            cons_show("Message notifications enabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_MESSAGE, TRUE);</span>
<span class='add'>+        } else if (strcmp(value, "off") == 0) {</span>
<span class='add'>+            cons_show("Message notifications disabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_MESSAGE, FALSE);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Usage: /notify message on|off");</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+    // set typing setting</span>
<span class='add'>+    } else if (strcmp(kind, "typing") == 0) {</span>
<span class='add'>+        if (strcmp(value, "on") == 0) {</span>
<span class='add'>+            cons_show("Typing notifications enabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_TYPING, TRUE);</span>
<span class='add'>+        } else if (strcmp(value, "off") == 0) {</span>
<span class='add'>+            cons_show("Typing notifications disabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_TYPING, FALSE);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Usage: /notify typing on|off");</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+    // set invite setting</span>
<span class='add'>+    } else if (strcmp(kind, "invite") == 0) {</span>
<span class='add'>+        if (strcmp(value, "on") == 0) {</span>
<span class='add'>+            cons_show("Chat room invite notifications enabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_INVITE, TRUE);</span>
<span class='add'>+        } else if (strcmp(value, "off") == 0) {</span>
<span class='add'>+            cons_show("Chat room invite notifications disabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_INVITE, FALSE);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Usage: /notify invite on|off");</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+    // set subscription setting</span>
<span class='add'>+    } else if (strcmp(kind, "sub") == 0) {</span>
<span class='add'>+        if (strcmp(value, "on") == 0) {</span>
<span class='add'>+            cons_show("Subscription notifications enabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_SUB, TRUE);</span>
<span class='add'>+        } else if (strcmp(value, "off") == 0) {</span>
<span class='add'>+            cons_show("Subscription notifications disabled.");</span>
<span class='add'>+            prefs_set_boolean(PREF_NOTIFY_SUB, FALSE);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Usage: /notify sub on|off");</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+    // set remind setting</span>
<span class='add'>+    } else if (strcmp(kind, "remind") == 0) {</span>
<span class='add'>+        gint period = atoi(value);</span>
<span class='add'>+        prefs_set_notify_remind(period);</span>
<span class='add'>+        if (period == 0) {</span>
<span class='add'>+            cons_show("Message reminders disabled.");</span>
<span class='add'>+        } else if (period == 1) {</span>
<span class='add'>+            cons_show("Message reminder period set to 1 second.");</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Message reminder period set to %d seconds.", period);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Unknown command: %s.", kind);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_log(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *subcmd = args[0];</span>
<span class='add'>+    char *value = args[1];</span>
<span class='add'>+    int intval;</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(subcmd, "maxsize") == 0) {</span>
<span class='add'>+        if (_strtoi(value, &amp;intval, PREFS_MIN_LOG_SIZE, INT_MAX) == 0) {</span>
<span class='add'>+            prefs_set_max_log_size(intval);</span>
<span class='add'>+            cons_show("Log maxinum size set to %d bytes", intval);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    /* TODO: make 'level' subcommand for debug level */</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_reconnect(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *value = args[0];</span>
<span class='add'>+    int intval;</span>
<span class='add'>+</span>
<span class='add'>+    if (_strtoi(value, &amp;intval, 0, INT_MAX) == 0) {</span>
<span class='add'>+        prefs_set_reconnect(intval);</span>
<span class='add'>+        if (intval == 0) {</span>
<span class='add'>+            cons_show("Reconnect disabled.", intval);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Reconnect interval set to %d seconds.", intval);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_autoping(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *value = args[0];</span>
<span class='add'>+    int intval;</span>
<span class='add'>+</span>
<span class='add'>+    if (_strtoi(value, &amp;intval, 0, INT_MAX) == 0) {</span>
<span class='add'>+        prefs_set_autoping(intval);</span>
<span class='add'>+        jabber_set_autoping(intval);</span>
<span class='add'>+        if (intval == 0) {</span>
<span class='add'>+            cons_show("Autoping disabled.", intval);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Autoping interval set to %d seconds.", intval);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_autoaway(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    char *setting = args[0];</span>
<span class='add'>+    char *value = args[1];</span>
<span class='add'>+    int minutesval;</span>
<span class='add'>+</span>
<span class='add'>+    if ((strcmp(setting, "mode") != 0) &amp;&amp; (strcmp(setting, "time") != 0) &amp;&amp;</span>
<span class='add'>+            (strcmp(setting, "message") != 0) &amp;&amp; (strcmp(setting, "check") != 0)) {</span>
<span class='add'>+        cons_show("Setting must be one of 'mode', 'time', 'message' or 'check'");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(setting, "mode") == 0) {</span>
<span class='add'>+        if ((strcmp(value, "idle") != 0) &amp;&amp; (strcmp(value, "away") != 0) &amp;&amp;</span>
<span class='add'>+                (strcmp(value, "off") != 0)) {</span>
<span class='add'>+            cons_show("Mode must be one of 'idle', 'away' or 'off'");</span>
<span class='add'>+        } else {</span>
<span class='add'>+            prefs_set_string(PREF_AUTOAWAY_MODE, value);</span>
<span class='add'>+            cons_show("Auto away mode set to: %s.", value);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(setting, "time") == 0) {</span>
<span class='add'>+        if (_strtoi(value, &amp;minutesval, 1, INT_MAX) == 0) {</span>
<span class='add'>+            prefs_set_autoaway_time(minutesval);</span>
<span class='add'>+            cons_show("Auto away time set to: %d minutes.", minutesval);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(setting, "message") == 0) {</span>
<span class='add'>+        if (strcmp(value, "off") == 0) {</span>
<span class='add'>+            prefs_set_string(PREF_AUTOAWAY_MESSAGE, NULL);</span>
<span class='add'>+            cons_show("Auto away message cleared.");</span>
<span class='add'>+        } else {</span>
<span class='add'>+            prefs_set_string(PREF_AUTOAWAY_MESSAGE, value);</span>
<span class='add'>+            cons_show("Auto away message set to: \"%s\".", value);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(setting, "check") == 0) {</span>
<span class='add'>+        return _cmd_set_boolean_preference(value, help, "Online check",</span>
<span class='add'>+            PREF_AUTOAWAY_CHECK);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_priority(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    char *value = args[0];</span>
<span class='add'>+    int intval;</span>
<span class='add'>+</span>
<span class='add'>+    if (_strtoi(value, &amp;intval, -128, 127) == 0) {</span>
<span class='add'>+        accounts_set_priority_all(jabber_get_account_name(), intval);</span>
<span class='add'>+        resource_presence_t last_presence = accounts_get_last_presence(jabber_get_account_name());</span>
<span class='add'>+        presence_update(last_presence, jabber_get_presence_message(), 0);</span>
<span class='add'>+        cons_show("Priority set to %d.", intval);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_statuses(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Status notifications", PREF_STATUSES);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_vercheck(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    int num_args = g_strv_length(args);</span>
<span class='add'>+</span>
<span class='add'>+    if (num_args == 0) {</span>
<span class='add'>+        cons_check_version(TRUE);</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    } else {</span>
<span class='add'>+        return _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+            "Version checking", PREF_VERCHECK);</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_flash(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Screen flash", PREF_FLASH);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_intype(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Show contact typing", PREF_INTYPE);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_splash(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Splash screen", PREF_SPLASH);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_autoconnect(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    if (strcmp(args[0], "off") == 0) {</span>
<span class='add'>+        prefs_set_string(PREF_CONNECT_ACCOUNT, NULL);</span>
<span class='add'>+        cons_show("Autoconnect account disabled.");</span>
<span class='add'>+    } else if (strcmp(args[0], "set") == 0) {</span>
<span class='add'>+        prefs_set_string(PREF_CONNECT_ACCOUNT, args[1]);</span>
<span class='add'>+        cons_show("Autoconnect account set to: %s.", args[1]);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+    }</span>
<span class='add'>+    return true;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_chlog(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Chat logging", PREF_CHLOG);</span>
<span class='add'>+</span>
<span class='add'>+    // if set to off, disable history</span>
<span class='add'>+    if (result == TRUE &amp;&amp; (strcmp(args[0], "off") == 0)) {</span>
<span class='add'>+        prefs_set_boolean(PREF_HISTORY, FALSE);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_grlog(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Groupchat logging", PREF_GRLOG);</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_mouse(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    return _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Mouse handling", PREF_MOUSE);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_history(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean result = _cmd_set_boolean_preference(args[0], help,</span>
<span class='add'>+        "Chat history", PREF_HISTORY);</span>
<span class='add'>+</span>
<span class='add'>+    // if set to on, set chlog</span>
<span class='add'>+    if (result == TRUE &amp;&amp; (strcmp(args[0], "on") == 0)) {</span>
<span class='add'>+        prefs_set_boolean(PREF_CHLOG, TRUE);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_away(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    _update_presence(RESOURCE_AWAY, "away", args);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_online(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    _update_presence(RESOURCE_ONLINE, "online", args);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_dnd(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    _update_presence(RESOURCE_DND, "dnd", args);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_chat(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    _update_presence(RESOURCE_CHAT, "chat", args);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_xa(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+    _update_presence(RESOURCE_XA, "xa", args);</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+cmd_otr(gchar **args, struct cmd_help_t help)</span>
<span class='add'>+{</span>
<span class='add'>+#ifdef HAVE_LIBOTR</span>
<span class='add'>+    if (strcmp(args[0], "gen") == 0) {</span>
<span class='add'>+        if (jabber_get_connection_status() != JABBER_CONNECTED) {</span>
<span class='add'>+            cons_show("You must be connected with an account to load OTR information.");</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        } else {</span>
<span class='add'>+            ProfAccount *account = accounts_get_account(jabber_get_account_name());</span>
<span class='add'>+            otr_account_load(account);</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+    } else {</span>
<span class='add'>+        cons_show("Usage: %s", help.usage);</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+#else</span>
<span class='add'>+    cons_show("This version of Profanity has not been build with OTR support enabled");</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+#endif</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+</span>
<span class='add'>+// helper function that asks the user for a password and saves it in passwd</span>
<span class='add'>+static char *</span>
<span class='add'>+_ask_password(void) {</span>
<span class='add'>+  char *passwd = malloc(sizeof(char) * (MAX_PASSWORD_SIZE + 1));</span>
<span class='add'>+  status_bar_get_password();</span>
<span class='add'>+  status_bar_refresh();</span>
<span class='add'>+  inp_block();</span>
<span class='add'>+  inp_get_password(passwd);</span>
<span class='add'>+  inp_non_block();</span>
<span class='add'>+</span>
<span class='add'>+  return passwd;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+// helper function for status change commands</span>
<span class='add'>+static void</span>
<span class='add'>+_update_presence(const resource_presence_t resource_presence,</span>
<span class='add'>+    const char * const show, gchar **args)</span>
<span class='add'>+{</span>
<span class='add'>+    char *msg = NULL;</span>
<span class='add'>+    int num_args = g_strv_length(args);</span>
<span class='add'>+    if (num_args == 1) {</span>
<span class='add'>+        msg = args[0];</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    jabber_conn_status_t conn_status = jabber_get_connection_status();</span>
<span class='add'>+</span>
<span class='add'>+    if (conn_status != JABBER_CONNECTED) {</span>
<span class='add'>+        cons_show("You are not currently connected.");</span>
<span class='add'>+    } else {</span>
<span class='add'>+        presence_update(resource_presence, msg, 0);</span>
<span class='add'>+</span>
<span class='add'>+        contact_presence_t contact_presence = contact_presence_from_resource_presence(resource_presence);</span>
<span class='add'>+        title_bar_set_status(contact_presence);</span>
<span class='add'>+</span>
<span class='add'>+        gint priority = accounts_get_priority_for_presence_type(jabber_get_account_name(), resource_presence);</span>
<span class='add'>+        if (msg != NULL) {</span>
<span class='add'>+            cons_show("Status set to %s (priority %d), \"%s\".", show, priority, msg);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            cons_show("Status set to %s (priority %d).", show, priority);</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+// helper function for boolean preference commands</span>
<span class='add'>+static gboolean</span>
<span class='add'>+_cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help,</span>
<span class='add'>+    const char * const display, preference_t pref)</span>
<span class='add'>+{</span>
<span class='add'>+    GString *enabled = g_string_new(display);</span>
<span class='add'>+    g_string_append(enabled, " enabled.");</span>
<span class='add'>+</span>
<span class='add'>+    GString *disabled = g_string_new(display);</span>
<span class='add'>+    g_string_append(disabled, " disabled.");</span>
<span class='add'>+</span>
<span class='add'>+    if (strcmp(arg, "on") == 0) {</span>
<span class='add'>+        cons_show(enabled-&gt;str);</span>
<span class='add'>+        prefs_set_boolean(pref, TRUE);</span>
<span class='add'>+    } else if (strcmp(arg, "off") == 0) {</span>
<span class='add'>+        cons_show(disabled-&gt;str);</span>
<span class='add'>+        prefs_set_boolean(pref, FALSE);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        char usage[strlen(help.usage) + 8];</span>
<span class='add'>+        sprintf(usage, "Usage: %s", help.usage);</span>
<span class='add'>+        cons_show(usage);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    g_string_free(enabled, TRUE);</span>
<span class='add'>+    g_string_free(disabled, TRUE);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static int</span>
<span class='add'>+_strtoi(char *str, int *saveptr, int min, int max)</span>
<span class='add'>+{</span>
<span class='add'>+    char *ptr;</span>
<span class='add'>+    int val;</span>
<span class='add'>+</span>
<span class='add'>+    errno = 0;</span>
<span class='add'>+    val = (int)strtol(str, &amp;ptr, 0);</span>
<span class='add'>+    if (*str == '\0' || *ptr != '\0') {</span>
<span class='add'>+        cons_show("Illegal character. Must be a number.");</span>
<span class='add'>+        return -1;</span>
<span class='add'>+    } else if (errno == ERANGE || val &lt; min || val &gt; max) {</span>
<span class='add'>+        cons_show("Value out of range. Must be in %d..%d.", min, max);</span>
<span class='add'>+        return -1;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    *saveptr = val;</span>
<span class='add'>+</span>
<span class='add'>+    return 0;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static void</span>
<span class='add'>+_cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size)</span>
<span class='add'>+{</span>
<span class='add'>+    cons_show("");</span>
<span class='add'>+    cons_show("%s", heading);</span>
<span class='add'>+    cons_show("");</span>
<span class='add'>+</span>
<span class='add'>+    GList *ordered_commands = NULL;</span>
<span class='add'>+    int i;</span>
<span class='add'>+    for (i = 0; i &lt; filter_size; i++) {</span>
<span class='add'>+        Command *cmd = g_hash_table_lookup(commands, cmd_filter[i]);</span>
<span class='add'>+        ordered_commands = g_list_insert_sorted(ordered_commands, cmd, (GCompareFunc)_compare_commands);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    GList *curr = ordered_commands;</span>
<span class='add'>+    while (curr != NULL) {</span>
<span class='add'>+        Command *cmd = curr-&gt;data;</span>
<span class='add'>+        cons_show("%-12s: %s", cmd-&gt;cmd, cmd-&gt;help.short_help);</span>
<span class='add'>+        curr = g_list_next(curr);</span>
<span class='add'>+    }</span>
<span class='add'>+    g_list_free(ordered_commands);</span>
<span class='add'>+    g_list_free(curr);</span>
<span class='add'>+</span>
<span class='add'>+    cons_show("");</span>
<span class='add'>+    cons_show("Use /help [command] without the leading slash, for help on a specific command");</span>
<span class='add'>+    cons_show("");</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static</span>
<span class='add'>+gint _compare_commands(Command *a, Command *b)</span>
<span class='add'>+{</span>
<span class='add'>+    const char * utf8_str_a = a-&gt;cmd;</span>
<span class='add'>+    const char * utf8_str_b = b-&gt;cmd;</span>
<span class='add'>+</span>
<span class='add'>+    gchar *key_a = g_utf8_collate_key(utf8_str_a, -1);</span>
<span class='add'>+    gchar *key_b = g_utf8_collate_key(utf8_str_b, -1);</span>
<span class='add'>+</span>
<span class='add'>+    gint result = g_strcmp0(key_a, key_b);</span>
<span class='add'>+</span>
<span class='add'>+    g_free(key_a);</span>
<span class='add'>+    g_free(key_b);</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='head'>diff --git a/src/command/commands.h b/src/command/commands.h
new file mode 100644
index 00000000..3caa3085
--- /dev/null
+++ b/<a href='/danisanti/profani-tty/tree/src/command/commands.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/command/commands.h</a>
</span><span class='hunk'>@@ -0,0 +1,113 @@</span>
<span class='add'>+/*</span>
<span class='add'>+ * commands.h</span>
<span class='add'>+ *</span>
<span class='add'>+ * Copyright (C) 2012, 2013 James Booth &lt;boothj5@gmail.com&gt;</span>
<span class='add'>+ *</span>
<span class='add'>+ * This file is part of Profanity.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is free software: you can redistribute it and/or modify</span>
<span class='add'>+ * it under the terms of the GNU General Public License as published by</span>
<span class='add'>+ * the Free Software Foundation, either version 3 of the License, or</span>
<span class='add'>+ * (at your option) any later version.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is distributed in the hope that it will be useful,</span>
<span class='add'>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class='add'>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class='add'>+ * GNU General Public License for more details.</span>
<span class='add'>+ *</span>
<span class='add'>+ * You should have received a copy of the GNU General Public License</span>
<span class='add'>+ * along with Profanity.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class='add'>+ *</span>
<span class='add'>+ */</span>
<span class='add'>+</span>
<span class='add'>+#ifndef COMMANDS_H</span>
<span class='add'>+#define COMMANDS_H</span>
<span class='add'>+</span>
<span class='add'>+// Command help strings</span>
<span class='add'>+typedef struct cmd_help_t {</span>
<span class='add'>+    const gchar *usage;</span>
<span class='add'>+    const gchar *short_help;</span>
<span class='add'>+    const gchar *long_help[50];</span>
<span class='add'>+} CommandHelp;</span>
<span class='add'>+</span>
<span class='add'>+/*</span>
<span class='add'>+ * Command structure</span>
<span class='add'>+ *</span>
<span class='add'>+ * cmd - The command string including leading '/'</span>
<span class='add'>+ * func - The function to execute for the command</span>
<span class='add'>+ * parser - The function used to parse arguments</span>
<span class='add'>+ * min_args - Minimum number of arguments</span>
<span class='add'>+ * max_args - Maximum number of arguments</span>
<span class='add'>+ * help - A help struct containing usage info etc</span>
<span class='add'>+ */</span>
<span class='add'>+typedef struct cmd_t {</span>
<span class='add'>+    gchar *cmd;</span>
<span class='add'>+    gboolean (*func)(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+    gchar** (*parser)(const char * const inp, int min, int max);</span>
<span class='add'>+    int min_args;</span>
<span class='add'>+    int max_args;</span>
<span class='add'>+    void (*setting_func)(void);</span>
<span class='add'>+    CommandHelp help;</span>
<span class='add'>+} Command;</span>
<span class='add'>+</span>
<span class='add'>+gboolean cmd_about(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_account(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_autoaway(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_autoconnect(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_autoping(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_away(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_beep(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_caps(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_chat(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_chlog(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_clear(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_close(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_connect(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_decline(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_disco(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_disconnect(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_dnd(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_duck(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_flash(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_gone(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_grlog(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_group(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_help(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_history(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_info(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_intype(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_invite(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_invites(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_join(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_leave(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_log(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_mouse(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_msg(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_nick(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_notify(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_online(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_otr(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_outtype(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_prefs(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_priority(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_quit(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_reconnect(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_rooms(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_bookmark(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_roster(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_software(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_splash(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_states(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_status(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_statuses(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_sub(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_theme(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_tiny(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_titlebar(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_vercheck(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_who(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_win(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_wins(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+gboolean cmd_xa(gchar **args, struct cmd_help_t help);</span>
<span class='add'>+</span>
<span class='add'>+#endif</span>
<span class='head'>diff --git a/src/contact.c b/src/contact.c
index 9cc992b2..0b955548 100644
--- a/<a href='/danisanti/profani-tty/tree/src/contact.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/contact.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/contact.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/contact.c</a>
</span><span class='hunk'>@@ -166,6 +166,31 @@ p_contact_name_or_jid(const PContact contact)</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='add'>+char *</span>
<span class='add'>+p_contact_create_display_string(const PContact contact, const char * const resource)</span>
<span class='add'>+{</span>
<span class='add'>+    GString *result_str = g_string_new("");</span>
<span class='add'>+</span>
<span class='add'>+    // use nickname if exists</span>
<span class='add'>+    if (contact-&gt;name != NULL) {</span>
<span class='add'>+        g_string_append(result_str, contact-&gt;name);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        g_string_append(result_str, contact-&gt;barejid);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // add resource if not default provided by profanity</span>
<span class='add'>+    if (strcmp(resource, "__prof_default") != 0) {</span>
<span class='add'>+        g_string_append(result_str, " (");</span>
<span class='add'>+        g_string_append(result_str, resource);</span>
<span class='add'>+        g_string_append(result_str, ")");</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    char *result = result_str-&gt;str;</span>
<span class='add'>+    g_string_free(result_str, FALSE);</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='ctx'> static Resource *</span>
<span class='ctx'> _highest_presence(Resource *first, Resource *second)</span>
<span class='ctx'> {</span>
<span class='head'>diff --git a/src/contact.h b/src/contact.h
index 20c0e3dd..b096c8d9 100644
--- a/<a href='/danisanti/profani-tty/tree/src/contact.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/contact.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/contact.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/contact.h</a>
</span><span class='hunk'>@@ -55,5 +55,6 @@ void p_contact_set_groups(const PContact contact, GSList *groups);</span>
<span class='ctx'> GSList * p_contact_groups(const PContact contact);</span>
<span class='ctx'> gboolean p_contact_in_group(const PContact contact, const char * const group);</span>
<span class='ctx'> gboolean p_contact_subscribed(const PContact contact);</span>
<span class='add'>+char * p_contact_create_display_string(const PContact contact, const char * const resource);</span>
<span class='ctx'> </span>
<span class='ctx'> #endif</span>
<span class='head'>diff --git a/src/profanity.c b/src/profanity.c
index 913f3350..486402e3 100644
--- a/<a href='/danisanti/profani-tty/tree/src/profanity.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/profanity.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/profanity.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/profanity.c</a>
</span><span class='hunk'>@@ -41,11 +41,11 @@</span>
<span class='ctx'> #include "command/command.h"</span>
<span class='ctx'> #include "common.h"</span>
<span class='ctx'> #include "contact.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "log.h"</span>
<span class='ctx'> #include "muc.h"</span>
<span class='ctx'> #include "otr.h"</span>
<span class='ctx'> #include "resource.h"</span>
<span class='del'>-#include "ui/notifier.h"</span>
<span class='ctx'> #include "ui/ui.h"</span>
<span class='ctx'> #include "xmpp/xmpp.h"</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -414,7 +414,7 @@ prof_handle_contact_online(char *contact, Resource *resource,</span>
<span class='ctx'> {</span>
<span class='ctx'>     gboolean updated = roster_update_presence(contact, resource, last_activity);</span>
<span class='ctx'> </span>
<span class='del'>-    if (updated) {</span>
<span class='add'>+    if (updated &amp;&amp; prefs_get_boolean(PREF_STATUSES)) {</span>
<span class='ctx'>         PContact result = roster_get_contact(contact);</span>
<span class='ctx'>         if (p_contact_subscription(result) != NULL) {</span>
<span class='ctx'>             if (strcmp(p_contact_subscription(result), "none") != 0) {</span>
<span class='hunk'>@@ -431,7 +431,7 @@ prof_handle_contact_offline(char *contact, char *resource, char *status)</span>
<span class='ctx'> {</span>
<span class='ctx'>     gboolean updated = roster_contact_offline(contact, resource, status);</span>
<span class='ctx'> </span>
<span class='del'>-    if (resource != NULL &amp;&amp; updated) {</span>
<span class='add'>+    if (resource != NULL &amp;&amp; updated &amp;&amp; prefs_get_boolean(PREF_STATUSES)) {</span>
<span class='ctx'>         Jid *jid = jid_create_from_bare_and_resource(contact, resource);</span>
<span class='ctx'>         PContact result = roster_get_contact(contact);</span>
<span class='ctx'>         if (p_contact_subscription(result) != NULL) {</span>
<span class='hunk'>@@ -465,7 +465,31 @@ prof_handle_idle(void)</span>
<span class='ctx'> {</span>
<span class='ctx'>     jabber_conn_status_t status = jabber_get_connection_status();</span>
<span class='ctx'>     if (status == JABBER_CONNECTED) {</span>
<span class='del'>-        ui_idle();</span>
<span class='add'>+        GSList *recipients = ui_get_recipients();</span>
<span class='add'>+        GSList *curr = recipients;</span>
<span class='add'>+</span>
<span class='add'>+        while (curr != NULL) {</span>
<span class='add'>+            char *recipient = curr-&gt;data;</span>
<span class='add'>+            chat_session_no_activity(recipient);</span>
<span class='add'>+</span>
<span class='add'>+            if (chat_session_is_gone(recipient) &amp;&amp;</span>
<span class='add'>+                    !chat_session_get_sent(recipient)) {</span>
<span class='add'>+                message_send_gone(recipient);</span>
<span class='add'>+            } else if (chat_session_is_inactive(recipient) &amp;&amp;</span>
<span class='add'>+                    !chat_session_get_sent(recipient)) {</span>
<span class='add'>+                message_send_inactive(recipient);</span>
<span class='add'>+            } else if (prefs_get_boolean(PREF_OUTTYPE) &amp;&amp;</span>
<span class='add'>+                    chat_session_is_paused(recipient) &amp;&amp;</span>
<span class='add'>+                    !chat_session_get_sent(recipient)) {</span>
<span class='add'>+                message_send_paused(recipient);</span>
<span class='add'>+            }</span>
<span class='add'>+</span>
<span class='add'>+            curr = g_slist_next(curr);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        if (recipients != NULL) {</span>
<span class='add'>+            g_slist_free(recipients);</span>
<span class='add'>+        }</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -666,7 +690,7 @@ _shutdown(void)</span>
<span class='ctx'>     prefs_close();</span>
<span class='ctx'>     theme_close();</span>
<span class='ctx'>     accounts_close();</span>
<span class='del'>-    cmd_close();</span>
<span class='add'>+    cmd_uninit();</span>
<span class='ctx'>     log_close();</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='head'>diff --git a/src/roster_list.c b/src/roster_list.c
new file mode 100644
index 00000000..fa00437b
--- /dev/null
+++ b/<a href='/danisanti/profani-tty/tree/src/roster_list.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/roster_list.c</a>
</span><span class='hunk'>@@ -0,0 +1,475 @@</span>
<span class='add'>+/*</span>
<span class='add'>+ * roster_list.c</span>
<span class='add'>+ *</span>
<span class='add'>+ * Copyright (C) 2012, 2013 James Booth &lt;boothj5@gmail.com&gt;</span>
<span class='add'>+ *</span>
<span class='add'>+ * This file is part of Profanity.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is free software: you can redistribute it and/or modify</span>
<span class='add'>+ * it under the terms of the GNU General Public License as published by</span>
<span class='add'>+ * the Free Software Foundation, either version 3 of the License, or</span>
<span class='add'>+ * (at your option) any later version.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is distributed in the hope that it will be useful,</span>
<span class='add'>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class='add'>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class='add'>+ * GNU General Public License for more details.</span>
<span class='add'>+ *</span>
<span class='add'>+ * You should have received a copy of the GNU General Public License</span>
<span class='add'>+ * along with Profanity.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class='add'>+ *</span>
<span class='add'>+ */</span>
<span class='add'>+</span>
<span class='add'>+</span>
<span class='add'>+#include &lt;string.h&gt;</span>
<span class='add'>+#include &lt;glib.h&gt;</span>
<span class='add'>+#include &lt;assert.h&gt;</span>
<span class='add'>+</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='add'>+#include "resource.h"</span>
<span class='add'>+#include "contact.h"</span>
<span class='add'>+#include "jid.h"</span>
<span class='add'>+#include "tools/autocomplete.h"</span>
<span class='add'>+#include "xmpp/xmpp.h"</span>
<span class='add'>+#include "profanity.h"</span>
<span class='add'>+</span>
<span class='add'>+// nicknames</span>
<span class='add'>+static Autocomplete name_ac;</span>
<span class='add'>+</span>
<span class='add'>+// barejids</span>
<span class='add'>+static Autocomplete barejid_ac;</span>
<span class='add'>+</span>
<span class='add'>+// fulljids</span>
<span class='add'>+static Autocomplete fulljid_ac;</span>
<span class='add'>+</span>
<span class='add'>+// groups</span>
<span class='add'>+static Autocomplete groups_ac;</span>
<span class='add'>+</span>
<span class='add'>+// contacts, indexed on barejid</span>
<span class='add'>+static GHashTable *contacts;</span>
<span class='add'>+</span>
<span class='add'>+// nickname to jid map</span>
<span class='add'>+static GHashTable *name_to_barejid;</span>
<span class='add'>+</span>
<span class='add'>+static gboolean _key_equals(void *key1, void *key2);</span>
<span class='add'>+static gboolean _datetimes_equal(GDateTime *dt1, GDateTime *dt2);</span>
<span class='add'>+static void _replace_name(const char * const current_name,</span>
<span class='add'>+    const char * const new_name, const char * const barejid);</span>
<span class='add'>+static void _add_name_and_barejid(const char * const name,</span>
<span class='add'>+    const char * const barejid);</span>
<span class='add'>+static gint _compare_contacts(PContact a, PContact b);</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_clear(void)</span>
<span class='add'>+{</span>
<span class='add'>+    autocomplete_clear(name_ac);</span>
<span class='add'>+    autocomplete_clear(barejid_ac);</span>
<span class='add'>+    autocomplete_clear(fulljid_ac);</span>
<span class='add'>+    autocomplete_clear(groups_ac);</span>
<span class='add'>+    g_hash_table_destroy(contacts);</span>
<span class='add'>+    contacts = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, g_free,</span>
<span class='add'>+        (GDestroyNotify)p_contact_free);</span>
<span class='add'>+    g_hash_table_destroy(name_to_barejid);</span>
<span class='add'>+    name_to_barejid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,</span>
<span class='add'>+        g_free);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+roster_update_presence(const char * const barejid, Resource *resource,</span>
<span class='add'>+    GDateTime *last_activity)</span>
<span class='add'>+{</span>
<span class='add'>+    assert(barejid != NULL);</span>
<span class='add'>+    assert(resource != NULL);</span>
<span class='add'>+</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+    if (contact == NULL) {</span>
<span class='add'>+        return FALSE;</span>
<span class='add'>+    }</span>
<span class='add'>+    if (!_datetimes_equal(p_contact_last_activity(contact), last_activity)) {</span>
<span class='add'>+        p_contact_set_last_activity(contact, last_activity);</span>
<span class='add'>+    }</span>
<span class='add'>+    p_contact_set_presence(contact, resource);</span>
<span class='add'>+    Jid *jid = jid_create_from_bare_and_resource(barejid, resource-&gt;name);</span>
<span class='add'>+    autocomplete_add(fulljid_ac, jid-&gt;fulljid);</span>
<span class='add'>+    jid_destroy(jid);</span>
<span class='add'>+</span>
<span class='add'>+    return TRUE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+PContact</span>
<span class='add'>+roster_get_contact(const char * const barejid)</span>
<span class='add'>+{</span>
<span class='add'>+    return g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+roster_contact_offline(const char * const barejid,</span>
<span class='add'>+    const char * const resource, const char * const status)</span>
<span class='add'>+{</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+</span>
<span class='add'>+    if (contact == NULL) {</span>
<span class='add'>+        return FALSE;</span>
<span class='add'>+    }</span>
<span class='add'>+    if (resource == NULL) {</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    } else {</span>
<span class='add'>+        gboolean result = p_contact_remove_resource(contact, resource);</span>
<span class='add'>+        if (result == TRUE) {</span>
<span class='add'>+            Jid *jid = jid_create_from_bare_and_resource(barejid, resource);</span>
<span class='add'>+            autocomplete_remove(fulljid_ac, jid-&gt;fulljid);</span>
<span class='add'>+            jid_destroy(jid);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        return result;</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_reset_search_attempts(void)</span>
<span class='add'>+{</span>
<span class='add'>+    autocomplete_reset(name_ac);</span>
<span class='add'>+    autocomplete_reset(barejid_ac);</span>
<span class='add'>+    autocomplete_reset(fulljid_ac);</span>
<span class='add'>+    autocomplete_reset(groups_ac);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_init(void)</span>
<span class='add'>+{</span>
<span class='add'>+    name_ac = autocomplete_new();</span>
<span class='add'>+    barejid_ac = autocomplete_new();</span>
<span class='add'>+    fulljid_ac = autocomplete_new();</span>
<span class='add'>+    groups_ac = autocomplete_new();</span>
<span class='add'>+    contacts = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, g_free,</span>
<span class='add'>+        (GDestroyNotify)p_contact_free);</span>
<span class='add'>+    name_to_barejid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,</span>
<span class='add'>+        g_free);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_free(void)</span>
<span class='add'>+{</span>
<span class='add'>+    autocomplete_free(name_ac);</span>
<span class='add'>+    autocomplete_free(barejid_ac);</span>
<span class='add'>+    autocomplete_free(fulljid_ac);</span>
<span class='add'>+    autocomplete_free(groups_ac);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_change_name(const char * const barejid, const char * const new_name)</span>
<span class='add'>+{</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+    const char * current_name = NULL;</span>
<span class='add'>+    if (p_contact_name(contact) != NULL) {</span>
<span class='add'>+        current_name = strdup(p_contact_name(contact));</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (contact != NULL) {</span>
<span class='add'>+        p_contact_set_name(contact, new_name);</span>
<span class='add'>+        _replace_name(current_name, new_name, barejid);</span>
<span class='add'>+</span>
<span class='add'>+        GSList *groups = p_contact_groups(contact);</span>
<span class='add'>+        roster_send_name_change(barejid, new_name, groups);</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_remove(const char * const name, const char * const barejid)</span>
<span class='add'>+{</span>
<span class='add'>+    autocomplete_remove(barejid_ac, barejid);</span>
<span class='add'>+    autocomplete_remove(name_ac, name);</span>
<span class='add'>+    g_hash_table_remove(name_to_barejid, name);</span>
<span class='add'>+</span>
<span class='add'>+    // remove each fulljid</span>
<span class='add'>+    PContact contact = roster_get_contact(barejid);</span>
<span class='add'>+    if (contact != NULL) {</span>
<span class='add'>+        GList *resources = p_contact_get_available_resources(contact);</span>
<span class='add'>+        while (resources != NULL) {</span>
<span class='add'>+            GString *fulljid = g_string_new(strdup(barejid));</span>
<span class='add'>+            g_string_append(fulljid, "/");</span>
<span class='add'>+            g_string_append(fulljid, resources-&gt;data);</span>
<span class='add'>+            autocomplete_remove(fulljid_ac, fulljid-&gt;str);</span>
<span class='add'>+            g_string_free(fulljid, TRUE);</span>
<span class='add'>+            resources = g_list_next(resources);</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // remove the contact</span>
<span class='add'>+    g_hash_table_remove(contacts, barejid);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_update(const char * const barejid, const char * const name,</span>
<span class='add'>+    GSList *groups, const char * const subscription, gboolean pending_out)</span>
<span class='add'>+{</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+</span>
<span class='add'>+    if (contact == NULL) {</span>
<span class='add'>+        roster_add(barejid, name, groups, subscription, pending_out, FALSE);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        p_contact_set_subscription(contact, subscription);</span>
<span class='add'>+        p_contact_set_pending_out(contact, pending_out);</span>
<span class='add'>+</span>
<span class='add'>+        const char * const new_name = name;</span>
<span class='add'>+        const char * current_name = NULL;</span>
<span class='add'>+        if (p_contact_name(contact) != NULL) {</span>
<span class='add'>+            current_name = strdup(p_contact_name(contact));</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        p_contact_set_name(contact, new_name);</span>
<span class='add'>+        p_contact_set_groups(contact, groups);</span>
<span class='add'>+        _replace_name(current_name, new_name, barejid);</span>
<span class='add'>+</span>
<span class='add'>+        // add groups</span>
<span class='add'>+        while (groups != NULL) {</span>
<span class='add'>+            autocomplete_add(groups_ac, groups-&gt;data);</span>
<span class='add'>+            groups = g_slist_next(groups);</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+roster_add(const char * const barejid, const char * const name, GSList *groups,</span>
<span class='add'>+    const char * const subscription, gboolean pending_out, gboolean from_initial)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean added = FALSE;</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+</span>
<span class='add'>+    if (contact == NULL) {</span>
<span class='add'>+        contact = p_contact_new(barejid, name, groups, subscription, NULL,</span>
<span class='add'>+            pending_out);</span>
<span class='add'>+</span>
<span class='add'>+        // add groups</span>
<span class='add'>+        while (groups != NULL) {</span>
<span class='add'>+            autocomplete_add(groups_ac, groups-&gt;data);</span>
<span class='add'>+            groups = g_slist_next(groups);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        g_hash_table_insert(contacts, strdup(barejid), contact);</span>
<span class='add'>+        autocomplete_add(barejid_ac, barejid);</span>
<span class='add'>+        _add_name_and_barejid(name, barejid);</span>
<span class='add'>+</span>
<span class='add'>+        if (!from_initial) {</span>
<span class='add'>+            prof_handle_roster_add(barejid, name);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        added = TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return added;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+char *</span>
<span class='add'>+roster_barejid_from_name(const char * const name)</span>
<span class='add'>+{</span>
<span class='add'>+    return g_hash_table_lookup(name_to_barejid, name);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+GSList *</span>
<span class='add'>+roster_get_contacts(void)</span>
<span class='add'>+{</span>
<span class='add'>+    GSList *result = NULL;</span>
<span class='add'>+    GHashTableIter iter;</span>
<span class='add'>+    gpointer key;</span>
<span class='add'>+    gpointer value;</span>
<span class='add'>+</span>
<span class='add'>+    g_hash_table_iter_init(&amp;iter, contacts);</span>
<span class='add'>+    while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='add'>+        result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_contacts);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // resturn all contact structs</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+roster_has_pending_subscriptions(void)</span>
<span class='add'>+{</span>
<span class='add'>+    GHashTableIter iter;</span>
<span class='add'>+    gpointer key;</span>
<span class='add'>+    gpointer value;</span>
<span class='add'>+</span>
<span class='add'>+    g_hash_table_iter_init(&amp;iter, contacts);</span>
<span class='add'>+    while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='add'>+        PContact contact = (PContact) value;</span>
<span class='add'>+        if (p_contact_pending_out(contact)) {</span>
<span class='add'>+            return TRUE;</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return FALSE;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+char *</span>
<span class='add'>+roster_find_contact(char *search_str)</span>
<span class='add'>+{</span>
<span class='add'>+    return autocomplete_complete(name_ac, search_str);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+char *</span>
<span class='add'>+roster_find_resource(char *search_str)</span>
<span class='add'>+{</span>
<span class='add'>+    return autocomplete_complete(fulljid_ac, search_str);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+GSList *</span>
<span class='add'>+roster_get_group(const char * const group)</span>
<span class='add'>+{</span>
<span class='add'>+    GSList *result = NULL;</span>
<span class='add'>+    GHashTableIter iter;</span>
<span class='add'>+    gpointer key;</span>
<span class='add'>+    gpointer value;</span>
<span class='add'>+</span>
<span class='add'>+    g_hash_table_iter_init(&amp;iter, contacts);</span>
<span class='add'>+    while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='add'>+        GSList *groups = p_contact_groups(value);</span>
<span class='add'>+        while (groups != NULL) {</span>
<span class='add'>+            if (strcmp(groups-&gt;data, group) == 0) {</span>
<span class='add'>+                result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_contacts);</span>
<span class='add'>+                break;</span>
<span class='add'>+            }</span>
<span class='add'>+            groups = g_slist_next(groups);</span>
<span class='add'>+        }</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    // resturn all contact structs</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_add_to_group(const char * const group, const char * const barejid)</span>
<span class='add'>+{</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+</span>
<span class='add'>+    if (contact != NULL) {</span>
<span class='add'>+        if (p_contact_in_group(contact, group)) {</span>
<span class='add'>+            if (p_contact_name(contact) != NULL) {</span>
<span class='add'>+                prof_handle_already_in_group(p_contact_name(contact), group);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                prof_handle_already_in_group(p_contact_barejid(contact), group);</span>
<span class='add'>+            }</span>
<span class='add'>+            return;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        roster_send_add_to_group(group, contact);</span>
<span class='add'>+</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+roster_remove_from_group(const char * const group, const char * const barejid)</span>
<span class='add'>+{</span>
<span class='add'>+    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='add'>+</span>
<span class='add'>+    if (contact != NULL) {</span>
<span class='add'>+        if (!p_contact_in_group(contact, group)) {</span>
<span class='add'>+            if (p_contact_name(contact) != NULL) {</span>
<span class='add'>+                prof_handle_not_in_group(p_contact_name(contact), group);</span>
<span class='add'>+            } else {</span>
<span class='add'>+                prof_handle_not_in_group(p_contact_barejid(contact), group);</span>
<span class='add'>+            }</span>
<span class='add'>+            return;</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        roster_send_remove_from_group(group, contact);</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+GSList *</span>
<span class='add'>+roster_get_groups(void)</span>
<span class='add'>+{</span>
<span class='add'>+    return autocomplete_get_list(groups_ac);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+char *</span>
<span class='add'>+roster_find_group(char *search_str)</span>
<span class='add'>+{</span>
<span class='add'>+    return autocomplete_complete(groups_ac, search_str);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+char *</span>
<span class='add'>+roster_find_jid(char *search_str)</span>
<span class='add'>+{</span>
<span class='add'>+    return autocomplete_complete(barejid_ac, search_str);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static</span>
<span class='add'>+gboolean _key_equals(void *key1, void *key2)</span>
<span class='add'>+{</span>
<span class='add'>+    gchar *str1 = (gchar *) key1;</span>
<span class='add'>+    gchar *str2 = (gchar *) key2;</span>
<span class='add'>+</span>
<span class='add'>+    return (g_strcmp0(str1, str2) == 0);</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static gboolean</span>
<span class='add'>+_datetimes_equal(GDateTime *dt1, GDateTime *dt2)</span>
<span class='add'>+{</span>
<span class='add'>+    if ((dt1 == NULL) &amp;&amp; (dt2 == NULL)) {</span>
<span class='add'>+        return TRUE;</span>
<span class='add'>+    } else if ((dt1 == NULL) &amp;&amp; (dt2 != NULL)) {</span>
<span class='add'>+        return FALSE;</span>
<span class='add'>+    } else if ((dt1 != NULL) &amp;&amp; (dt2 == NULL)) {</span>
<span class='add'>+        return FALSE;</span>
<span class='add'>+    } else {</span>
<span class='add'>+        return g_date_time_equal(dt1, dt2);</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static void</span>
<span class='add'>+_replace_name(const char * const current_name, const char * const new_name,</span>
<span class='add'>+    const char * const barejid)</span>
<span class='add'>+{</span>
<span class='add'>+    // current handle exists already</span>
<span class='add'>+    if (current_name != NULL) {</span>
<span class='add'>+        autocomplete_remove(name_ac, current_name);</span>
<span class='add'>+        g_hash_table_remove(name_to_barejid, current_name);</span>
<span class='add'>+        _add_name_and_barejid(new_name, barejid);</span>
<span class='add'>+    // no current handle</span>
<span class='add'>+    } else if (new_name != NULL) {</span>
<span class='add'>+        autocomplete_remove(name_ac, barejid);</span>
<span class='add'>+        g_hash_table_remove(name_to_barejid, barejid);</span>
<span class='add'>+        _add_name_and_barejid(new_name, barejid);</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static void</span>
<span class='add'>+_add_name_and_barejid(const char * const name, const char * const barejid)</span>
<span class='add'>+{</span>
<span class='add'>+    if (name != NULL) {</span>
<span class='add'>+        autocomplete_add(name_ac, name);</span>
<span class='add'>+        g_hash_table_insert(name_to_barejid, strdup(name), strdup(barejid));</span>
<span class='add'>+    } else {</span>
<span class='add'>+        autocomplete_add(name_ac, barejid);</span>
<span class='add'>+        g_hash_table_insert(name_to_barejid, strdup(barejid), strdup(barejid));</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+static</span>
<span class='add'>+gint _compare_contacts(PContact a, PContact b)</span>
<span class='add'>+{</span>
<span class='add'>+    const char * utf8_str_a = NULL;</span>
<span class='add'>+    const char * utf8_str_b = NULL;</span>
<span class='add'>+</span>
<span class='add'>+    if (p_contact_name(a) != NULL) {</span>
<span class='add'>+        utf8_str_a = p_contact_name(a);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        utf8_str_a = p_contact_barejid(a);</span>
<span class='add'>+    }</span>
<span class='add'>+    if (p_contact_name(b) != NULL) {</span>
<span class='add'>+        utf8_str_b = p_contact_name(b);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        utf8_str_b = p_contact_barejid(b);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    gchar *key_a = g_utf8_collate_key(utf8_str_a, -1);</span>
<span class='add'>+    gchar *key_b = g_utf8_collate_key(utf8_str_b, -1);</span>
<span class='add'>+</span>
<span class='add'>+    gint result = g_strcmp0(key_a, key_b);</span>
<span class='add'>+</span>
<span class='add'>+    g_free(key_a);</span>
<span class='add'>+    g_free(key_b);</span>
<span class='add'>+</span>
<span class='add'>+    return result;</span>
<span class='add'>+}</span>
<span class='head'>diff --git a/src/roster_list.h b/src/roster_list.h
new file mode 100644
index 00000000..9382081b
--- /dev/null
+++ b/<a href='/danisanti/profani-tty/tree/src/roster_list.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/roster_list.h</a>
</span><span class='hunk'>@@ -0,0 +1,58 @@</span>
<span class='add'>+/*</span>
<span class='add'>+ * roster_list.h</span>
<span class='add'>+ *</span>
<span class='add'>+ * Copyright (C) 2012, 2013 James Booth &lt;boothj5@gmail.com&gt;</span>
<span class='add'>+ *</span>
<span class='add'>+ * This file is part of Profanity.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is free software: you can redistribute it and/or modify</span>
<span class='add'>+ * it under the terms of the GNU General Public License as published by</span>
<span class='add'>+ * the Free Software Foundation, either version 3 of the License, or</span>
<span class='add'>+ * (at your option) any later version.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is distributed in the hope that it will be useful,</span>
<span class='add'>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class='add'>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class='add'>+ * GNU General Public License for more details.</span>
<span class='add'>+ *</span>
<span class='add'>+ * You should have received a copy of the GNU General Public License</span>
<span class='add'>+ * along with Profanity.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class='add'>+ *</span>
<span class='add'>+ */</span>
<span class='add'>+</span>
<span class='add'>+#ifndef ROSTER_LIST_H</span>
<span class='add'>+#define ROSTER_LIST_H</span>
<span class='add'>+</span>
<span class='add'>+#include &lt;glib.h&gt;</span>
<span class='add'>+</span>
<span class='add'>+#include "resource.h"</span>
<span class='add'>+#include "contact.h"</span>
<span class='add'>+</span>
<span class='add'>+void roster_clear(void);</span>
<span class='add'>+gboolean roster_update_presence(const char * const barejid, Resource *resource,</span>
<span class='add'>+    GDateTime *last_activity);</span>
<span class='add'>+PContact roster_get_contact(const char * const barejid);</span>
<span class='add'>+gboolean roster_contact_offline(const char * const barejid,</span>
<span class='add'>+    const char * const resource, const char * const status);</span>
<span class='add'>+void roster_reset_search_attempts(void);</span>
<span class='add'>+void roster_init(void);</span>
<span class='add'>+void roster_free(void);</span>
<span class='add'>+void roster_change_name(const char * const barejid, const char * const new_name);</span>
<span class='add'>+void roster_remove(const char * const name, const char * const barejid);</span>
<span class='add'>+void roster_update(const char * const barejid, const char * const name,</span>
<span class='add'>+    GSList *groups, const char * const subscription, gboolean pending_out);</span>
<span class='add'>+gboolean roster_add(const char * const barejid, const char * const name, GSList *groups,</span>
<span class='add'>+    const char * const subscription, gboolean pending_out, gboolean from_initial);</span>
<span class='add'>+char * roster_barejid_from_name(const char * const name);</span>
<span class='add'>+GSList * roster_get_contacts(void);</span>
<span class='add'>+gboolean roster_has_pending_subscriptions(void);</span>
<span class='add'>+char * roster_find_contact(char *search_str);</span>
<span class='add'>+char * roster_find_resource(char *search_str);</span>
<span class='add'>+GSList * roster_get_group(const char * const group);</span>
<span class='add'>+GSList * roster_get_groups(void);</span>
<span class='add'>+void roster_add_to_group(const char * const group, const char * const barejid);</span>
<span class='add'>+void roster_remove_from_group(const char * const group, const char * const barejid);</span>
<span class='add'>+char * roster_find_group(char *search_str);</span>
<span class='add'>+char * roster_find_jid(char *search_str);</span>
<span class='add'>+</span>
<span class='add'>+#endif</span>
<span class='head'>diff --git a/src/ui/console.c b/src/ui/console.c
index bbf0cef6..00e891db 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/console.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/console.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/console.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/console.c</a>
</span><span class='hunk'>@@ -31,9 +31,9 @@</span>
<span class='ctx'> </span>
<span class='ctx'> #include "command/command.h"</span>
<span class='ctx'> #include "common.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "config/preferences.h"</span>
<span class='ctx'> #include "config/theme.h"</span>
<span class='del'>-#include "ui/notifier.h"</span>
<span class='ctx'> #include "ui/window.h"</span>
<span class='ctx'> #include "ui/windows.h"</span>
<span class='ctx'> #include "ui/ui.h"</span>
<span class='hunk'>@@ -51,7 +51,7 @@ void</span>
<span class='ctx'> cons_show_time(void)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *console = wins_get_console();</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wins_refresh_console();</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -72,7 +72,7 @@ cons_debug(const char * const msg, ...)</span>
<span class='ctx'>         va_start(arg, msg);</span>
<span class='ctx'>         GString *fmt_msg = g_string_new(NULL);</span>
<span class='ctx'>         g_string_vprintf(fmt_msg, msg, arg);</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(console-&gt;win, "%s\n", fmt_msg-&gt;str);</span>
<span class='ctx'>         g_string_free(fmt_msg, TRUE);</span>
<span class='ctx'>         va_end(arg);</span>
<span class='hunk'>@@ -93,7 +93,7 @@ cons_show(const char * const msg, ...)</span>
<span class='ctx'>     va_start(arg, msg);</span>
<span class='ctx'>     GString *fmt_msg = g_string_new(NULL);</span>
<span class='ctx'>     g_string_vprintf(fmt_msg, msg, arg);</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "%s\n", fmt_msg-&gt;str);</span>
<span class='ctx'>     g_string_free(fmt_msg, TRUE);</span>
<span class='ctx'>     va_end(arg);</span>
<span class='hunk'>@@ -108,7 +108,7 @@ cons_show_error(const char * const msg, ...)</span>
<span class='ctx'>     va_start(arg, msg);</span>
<span class='ctx'>     GString *fmt_msg = g_string_new(NULL);</span>
<span class='ctx'>     g_string_vprintf(fmt_msg, msg, arg);</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_ERROR);</span>
<span class='ctx'>     wprintw(console-&gt;win, "%s\n", fmt_msg-&gt;str);</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_ERROR);</span>
<span class='hunk'>@@ -131,10 +131,7 @@ cons_show_typing(const char * const barejid)</span>
<span class='ctx'>         display_usr = barejid;</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='del'>-    wattron(console-&gt;win, COLOUR_TYPING);</span>
<span class='del'>-    wprintw(console-&gt;win, "!! %s is typing a message...\n", display_usr);</span>
<span class='del'>-    wattroff(console-&gt;win, COLOUR_TYPING);</span>
<span class='add'>+    win_print_line(console, '-', COLOUR_TYPING, "!! %s is typing a message...", display_usr);</span>
<span class='ctx'> </span>
<span class='ctx'>     wins_refresh_console();</span>
<span class='ctx'>     cons_alert();</span>
<span class='hunk'>@@ -149,7 +146,7 @@ cons_show_incoming_message(const char * const short_from, const int win_index)</span>
<span class='ctx'>     if (ui_index == 10) {</span>
<span class='ctx'>         ui_index = 0;</span>
<span class='ctx'>     }</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_INCOMING);</span>
<span class='ctx'>     wprintw(console-&gt;win, "&lt;&lt; incoming from %s (%d)\n", short_from, ui_index);</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_INCOMING);</span>
<span class='hunk'>@@ -168,7 +165,7 @@ cons_about(void)</span>
<span class='ctx'>     if (prefs_get_boolean(PREF_SPLASH)) {</span>
<span class='ctx'>         _cons_splash_logo();</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'> </span>
<span class='ctx'> </span>
<span class='ctx'>         if (strcmp(PACKAGE_STATUS, "development") == 0) {</span>
<span class='hunk'>@@ -182,22 +179,22 @@ cons_about(void)</span>
<span class='ctx'>         }</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "Copyright (C) 2012, 2013 James Booth &lt;%s&gt;.\n", PACKAGE_BUGREPORT);</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "This is free software; you are free to change and redistribute it.\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'> </span>
<span class='ctx'>     wprintw(console-&gt;win, "There is NO WARRANTY, to the extent permitted by law.\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "Type '/help' to show complete help.\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "\n");</span>
<span class='ctx'> </span>
<span class='ctx'>     if (prefs_get_boolean(PREF_VERCHECK)) {</span>
<span class='hunk'>@@ -221,12 +218,12 @@ cons_check_version(gboolean not_available_msg)</span>
<span class='ctx'> </span>
<span class='ctx'>         if (relase_valid) {</span>
<span class='ctx'>             if (release_is_new(latest_release)) {</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(console-&gt;win, "A new version of Profanity is available: %s", latest_release);</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(console-&gt;win, "Check &lt;http://www.profanity.im&gt; for details.\n");</span>
<span class='ctx'>                 free(latest_release);</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(console-&gt;win, "\n");</span>
<span class='ctx'>             } else {</span>
<span class='ctx'>                 if (not_available_msg) {</span>
<span class='hunk'>@@ -245,15 +242,15 @@ void</span>
<span class='ctx'> cons_show_login_success(ProfAccount *account)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *console = wins_get_console();</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "%s logged in successfully, ", account-&gt;jid);</span>
<span class='ctx'> </span>
<span class='ctx'>     resource_presence_t presence = accounts_get_login_presence(account-&gt;name);</span>
<span class='ctx'>     const char *presence_str = string_from_resource_presence(presence);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;presence_colour_on(console, presence_str);</span>
<span class='add'>+    win_presence_colour_on(console, presence_str);</span>
<span class='ctx'>     wprintw(console-&gt;win, "%s", presence_str);</span>
<span class='del'>-    console-&gt;presence_colour_off(console, presence_str);</span>
<span class='add'>+    win_presence_colour_off(console, presence_str);</span>
<span class='ctx'>     wprintw(console-&gt;win, " (priority %d)",</span>
<span class='ctx'>         accounts_get_priority_for_presence_type(account-&gt;name, presence));</span>
<span class='ctx'>     wprintw(console-&gt;win, ".\n");</span>
<span class='hunk'>@@ -271,7 +268,7 @@ cons_show_wins(void)</span>
<span class='ctx'> </span>
<span class='ctx'>     GSList *curr = window_strings;</span>
<span class='ctx'>     while (curr != NULL) {</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(console-&gt;win, curr-&gt;data);</span>
<span class='ctx'>         wprintw(console-&gt;win, "\n");</span>
<span class='ctx'>         curr = g_slist_next(curr);</span>
<span class='hunk'>@@ -313,19 +310,19 @@ cons_show_info(PContact pcontact)</span>
<span class='ctx'>     GDateTime *last_activity = p_contact_last_activity(pcontact);</span>
<span class='ctx'>     WINDOW *win = console-&gt;win;</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(win, "\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='del'>-    console-&gt;presence_colour_on(console, presence);</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='add'>+    win_presence_colour_on(console, presence);</span>
<span class='ctx'>     wprintw(win, "%s", barejid);</span>
<span class='ctx'>     if (name != NULL) {</span>
<span class='ctx'>         wprintw(win, " (%s)", name);</span>
<span class='ctx'>     }</span>
<span class='del'>-    console-&gt;presence_colour_off(console, presence);</span>
<span class='add'>+    win_presence_colour_off(console, presence);</span>
<span class='ctx'>     wprintw(win, ":\n");</span>
<span class='ctx'> </span>
<span class='ctx'>     if (sub != NULL) {</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(win, "Subscription: %s\n", sub);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -333,7 +330,7 @@ cons_show_info(PContact pcontact)</span>
<span class='ctx'>         GDateTime *now = g_date_time_new_now_local();</span>
<span class='ctx'>         GTimeSpan span = g_date_time_difference(now, last_activity);</span>
<span class='ctx'> </span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(win, "Last activity: ");</span>
<span class='ctx'> </span>
<span class='ctx'>         int hours = span / G_TIME_SPAN_HOUR;</span>
<span class='hunk'>@@ -355,7 +352,7 @@ cons_show_info(PContact pcontact)</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     if (resources != NULL) {</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(win, "Resources:\n");</span>
<span class='ctx'> </span>
<span class='ctx'>         // sort in order of availabiltiy</span>
<span class='hunk'>@@ -370,21 +367,21 @@ cons_show_info(PContact pcontact)</span>
<span class='ctx'>     while (ordered_resources != NULL) {</span>
<span class='ctx'>         Resource *resource = ordered_resources-&gt;data;</span>
<span class='ctx'>         const char *resource_presence = string_from_resource_presence(resource-&gt;presence);</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='del'>-        console-&gt;presence_colour_on(console, resource_presence);</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='add'>+        win_presence_colour_on(console, resource_presence);</span>
<span class='ctx'>         wprintw(win, "  %s (%d), %s", resource-&gt;name, resource-&gt;priority, resource_presence);</span>
<span class='ctx'>         if (resource-&gt;status != NULL) {</span>
<span class='ctx'>             wprintw(win, ", \"%s\"", resource-&gt;status);</span>
<span class='ctx'>         }</span>
<span class='ctx'>         wprintw(win, "\n");</span>
<span class='del'>-        console-&gt;presence_colour_off(console, resource_presence);</span>
<span class='add'>+        win_presence_colour_off(console, resource_presence);</span>
<span class='ctx'> </span>
<span class='ctx'>         if (resource-&gt;caps_str != NULL) {</span>
<span class='ctx'>             Capabilities *caps = caps_get(resource-&gt;caps_str);</span>
<span class='ctx'>             if (caps != NULL) {</span>
<span class='ctx'>                 // show identity</span>
<span class='ctx'>                 if ((caps-&gt;category != NULL) || (caps-&gt;type != NULL) || (caps-&gt;name != NULL)) {</span>
<span class='del'>-                    console-&gt;print_time(console, '-');</span>
<span class='add'>+                    win_print_time(console, '-');</span>
<span class='ctx'>                     wprintw(win, "    Identity: ");</span>
<span class='ctx'>                     if (caps-&gt;name != NULL) {</span>
<span class='ctx'>                         wprintw(win, "%s", caps-&gt;name);</span>
<span class='hunk'>@@ -404,7 +401,7 @@ cons_show_info(PContact pcontact)</span>
<span class='ctx'>                     wprintw(win, "\n");</span>
<span class='ctx'>                 }</span>
<span class='ctx'>                 if (caps-&gt;software != NULL) {</span>
<span class='del'>-                    console-&gt;print_time(console, '-');</span>
<span class='add'>+                    win_print_time(console, '-');</span>
<span class='ctx'>                     wprintw(win, "    Software: %s", caps-&gt;software);</span>
<span class='ctx'>                 }</span>
<span class='ctx'>                 if (caps-&gt;software_version != NULL) {</span>
<span class='hunk'>@@ -414,7 +411,7 @@ cons_show_info(PContact pcontact)</span>
<span class='ctx'>                     wprintw(win, "\n");</span>
<span class='ctx'>                 }</span>
<span class='ctx'>                 if (caps-&gt;os != NULL) {</span>
<span class='del'>-                    console-&gt;print_time(console, '-');</span>
<span class='add'>+                    win_print_time(console, '-');</span>
<span class='ctx'>                     wprintw(win, "    OS: %s", caps-&gt;os);</span>
<span class='ctx'>                 }</span>
<span class='ctx'>                 if (caps-&gt;os_version != NULL) {</span>
<span class='hunk'>@@ -440,10 +437,10 @@ cons_show_caps(const char * const contact, Resource *resource)</span>
<span class='ctx'>     WINDOW *win = console-&gt;win;</span>
<span class='ctx'>     cons_show("");</span>
<span class='ctx'>     const char *resource_presence = string_from_resource_presence(resource-&gt;presence);</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='del'>-    console-&gt;presence_colour_on(console, resource_presence);</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='add'>+    win_presence_colour_on(console, resource_presence);</span>
<span class='ctx'>     wprintw(console-&gt;win, "%s", contact);</span>
<span class='del'>-    console-&gt;presence_colour_off(console, resource_presence);</span>
<span class='add'>+    win_presence_colour_off(console, resource_presence);</span>
<span class='ctx'>     wprintw(win, ":\n");</span>
<span class='ctx'> </span>
<span class='ctx'>     if (resource-&gt;caps_str != NULL) {</span>
<span class='hunk'>@@ -451,7 +448,7 @@ cons_show_caps(const char * const contact, Resource *resource)</span>
<span class='ctx'>         if (caps != NULL) {</span>
<span class='ctx'>             // show identity</span>
<span class='ctx'>             if ((caps-&gt;category != NULL) || (caps-&gt;type != NULL) || (caps-&gt;name != NULL)) {</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(win, "Identity: ");</span>
<span class='ctx'>                 if (caps-&gt;name != NULL) {</span>
<span class='ctx'>                     wprintw(win, "%s", caps-&gt;name);</span>
<span class='hunk'>@@ -471,7 +468,7 @@ cons_show_caps(const char * const contact, Resource *resource)</span>
<span class='ctx'>                 wprintw(win, "\n");</span>
<span class='ctx'>             }</span>
<span class='ctx'>             if (caps-&gt;software != NULL) {</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(win, "Software: %s", caps-&gt;software);</span>
<span class='ctx'>             }</span>
<span class='ctx'>             if (caps-&gt;software_version != NULL) {</span>
<span class='hunk'>@@ -481,7 +478,7 @@ cons_show_caps(const char * const contact, Resource *resource)</span>
<span class='ctx'>                 wprintw(win, "\n");</span>
<span class='ctx'>             }</span>
<span class='ctx'>             if (caps-&gt;os != NULL) {</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(win, "OS: %s", caps-&gt;os);</span>
<span class='ctx'>             }</span>
<span class='ctx'>             if (caps-&gt;os_version != NULL) {</span>
<span class='hunk'>@@ -492,11 +489,11 @@ cons_show_caps(const char * const contact, Resource *resource)</span>
<span class='ctx'>             }</span>
<span class='ctx'> </span>
<span class='ctx'>             if (caps-&gt;features != NULL) {</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='ctx'>                 wprintw(win, "Features:\n");</span>
<span class='ctx'>                 GSList *feature = caps-&gt;features;</span>
<span class='ctx'>                 while (feature != NULL) {</span>
<span class='del'>-                    console-&gt;print_time(console, '-');</span>
<span class='add'>+                    win_print_time(console, '-');</span>
<span class='ctx'>                     wprintw(win, "  %s\n", feature-&gt;data);</span>
<span class='ctx'>                     feature = g_slist_next(feature);</span>
<span class='ctx'>                 }</span>
<span class='hunk'>@@ -515,10 +512,10 @@ cons_show_software_version(const char * const jid, const char * const  presence,</span>
<span class='ctx'>     ProfWin *console = wins_get_console();</span>
<span class='ctx'>     if ((name != NULL) || (version != NULL) || (os != NULL)) {</span>
<span class='ctx'>         cons_show("");</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='del'>-        console-&gt;presence_colour_on(console, presence);</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='add'>+        win_presence_colour_on(console, presence);</span>
<span class='ctx'>         wprintw(console-&gt;win, "%s", jid);</span>
<span class='del'>-        console-&gt;presence_colour_off(console, presence);</span>
<span class='add'>+        win_presence_colour_off(console, presence);</span>
<span class='ctx'>         wprintw(console-&gt;win, ":\n");</span>
<span class='ctx'>     }</span>
<span class='ctx'>     if (name != NULL) {</span>
<span class='hunk'>@@ -585,7 +582,7 @@ cons_show_room_list(GSList *rooms, const char * const conference_node)</span>
<span class='ctx'>         cons_show("Chat rooms at %s:", conference_node);</span>
<span class='ctx'>         while (rooms != NULL) {</span>
<span class='ctx'>             DiscoItem *room = rooms-&gt;data;</span>
<span class='del'>-            console-&gt;print_time(console, '-');</span>
<span class='add'>+            win_print_time(console, '-');</span>
<span class='ctx'>             wprintw(console-&gt;win, "  %s", room-&gt;jid);</span>
<span class='ctx'>             if (room-&gt;name != NULL) {</span>
<span class='ctx'>                 wprintw(console-&gt;win, ", (%s)", room-&gt;name);</span>
<span class='hunk'>@@ -615,7 +612,7 @@ cons_show_bookmarks(const GList *list)</span>
<span class='ctx'> </span>
<span class='ctx'>         ProfWin *console = wins_get_console();</span>
<span class='ctx'> </span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(console-&gt;win, "  %s", item-&gt;jid);</span>
<span class='ctx'>         if (item-&gt;nick != NULL) {</span>
<span class='ctx'>             wprintw(console-&gt;win, "/%s", item-&gt;nick);</span>
<span class='hunk'>@@ -683,7 +680,7 @@ cons_show_disco_items(GSList *items, const char * const jid)</span>
<span class='ctx'>         cons_show("Service discovery items for %s:", jid);</span>
<span class='ctx'>         while (items != NULL) {</span>
<span class='ctx'>             DiscoItem *item = items-&gt;data;</span>
<span class='del'>-            console-&gt;print_time(console, '-');</span>
<span class='add'>+            win_print_time(console, '-');</span>
<span class='ctx'>             wprintw(console-&gt;win, "  %s", item-&gt;jid);</span>
<span class='ctx'>             if (item-&gt;name != NULL) {</span>
<span class='ctx'>                 wprintw(console-&gt;win, ", (%s)", item-&gt;name);</span>
<span class='hunk'>@@ -706,7 +703,7 @@ cons_show_status(const char * const barejid)</span>
<span class='ctx'>     PContact pcontact = roster_get_contact(barejid);</span>
<span class='ctx'> </span>
<span class='ctx'>     if (pcontact != NULL) {</span>
<span class='del'>-        console-&gt;show_contact(console, pcontact);</span>
<span class='add'>+        win_show_contact(console, pcontact);</span>
<span class='ctx'>     } else {</span>
<span class='ctx'>         cons_show("No such contact \"%s\" in roster.", barejid);</span>
<span class='ctx'>     }</span>
<span class='hunk'>@@ -763,10 +760,10 @@ cons_show_account_list(gchar **accounts)</span>
<span class='ctx'>             if ((jabber_get_connection_status() == JABBER_CONNECTED) &amp;&amp;</span>
<span class='ctx'>                     (g_strcmp0(jabber_get_account_name(), accounts[i]) == 0)) {</span>
<span class='ctx'>                 resource_presence_t presence = accounts_get_last_presence(accounts[i]);</span>
<span class='del'>-                console-&gt;print_time(console, '-');</span>
<span class='del'>-                console-&gt;presence_colour_on(console, string_from_resource_presence(presence));</span>
<span class='add'>+                win_print_time(console, '-');</span>
<span class='add'>+                win_presence_colour_on(console, string_from_resource_presence(presence));</span>
<span class='ctx'>                 wprintw(console-&gt;win, "%s\n", accounts[i]);</span>
<span class='del'>-                console-&gt;presence_colour_off(console, string_from_resource_presence(presence));</span>
<span class='add'>+                win_presence_colour_off(console, string_from_resource_presence(presence));</span>
<span class='ctx'>             } else {</span>
<span class='ctx'>                 cons_show(accounts[i]);</span>
<span class='ctx'>             }</span>
<span class='hunk'>@@ -825,7 +822,7 @@ cons_show_account(ProfAccount *account)</span>
<span class='ctx'> </span>
<span class='ctx'>         WINDOW *win = console-&gt;win;</span>
<span class='ctx'>         if (resources != NULL) {</span>
<span class='del'>-            console-&gt;print_time(console, '-');</span>
<span class='add'>+            win_print_time(console, '-');</span>
<span class='ctx'>             wprintw(win, "Resources:\n");</span>
<span class='ctx'> </span>
<span class='ctx'>             // sort in order of availabiltiy</span>
<span class='hunk'>@@ -840,21 +837,21 @@ cons_show_account(ProfAccount *account)</span>
<span class='ctx'>         while (ordered_resources != NULL) {</span>
<span class='ctx'>             Resource *resource = ordered_resources-&gt;data;</span>
<span class='ctx'>             const char *resource_presence = string_from_resource_presence(resource-&gt;presence);</span>
<span class='del'>-            console-&gt;print_time(console, '-');</span>
<span class='del'>-            console-&gt;presence_colour_on(console, resource_presence);</span>
<span class='add'>+            win_print_time(console, '-');</span>
<span class='add'>+            win_presence_colour_on(console, resource_presence);</span>
<span class='ctx'>             wprintw(win, "  %s (%d), %s", resource-&gt;name, resource-&gt;priority, resource_presence);</span>
<span class='ctx'>             if (resource-&gt;status != NULL) {</span>
<span class='ctx'>                 wprintw(win, ", \"%s\"", resource-&gt;status);</span>
<span class='ctx'>             }</span>
<span class='ctx'>             wprintw(win, "\n");</span>
<span class='del'>-            console-&gt;presence_colour_off(console, resource_presence);</span>
<span class='add'>+            win_presence_colour_off(console, resource_presence);</span>
<span class='ctx'> </span>
<span class='ctx'>             if (resource-&gt;caps_str != NULL) {</span>
<span class='ctx'>                 Capabilities *caps = caps_get(resource-&gt;caps_str);</span>
<span class='ctx'>                 if (caps != NULL) {</span>
<span class='ctx'>                     // show identity</span>
<span class='ctx'>                     if ((caps-&gt;category != NULL) || (caps-&gt;type != NULL) || (caps-&gt;name != NULL)) {</span>
<span class='del'>-                        console-&gt;print_time(console, '-');</span>
<span class='add'>+                        win_print_time(console, '-');</span>
<span class='ctx'>                         wprintw(win, "    Identity: ");</span>
<span class='ctx'>                         if (caps-&gt;name != NULL) {</span>
<span class='ctx'>                             wprintw(win, "%s", caps-&gt;name);</span>
<span class='hunk'>@@ -874,7 +871,7 @@ cons_show_account(ProfAccount *account)</span>
<span class='ctx'>                         wprintw(win, "\n");</span>
<span class='ctx'>                     }</span>
<span class='ctx'>                     if (caps-&gt;software != NULL) {</span>
<span class='del'>-                        console-&gt;print_time(console, '-');</span>
<span class='add'>+                        win_print_time(console, '-');</span>
<span class='ctx'>                         wprintw(win, "    Software: %s", caps-&gt;software);</span>
<span class='ctx'>                     }</span>
<span class='ctx'>                     if (caps-&gt;software_version != NULL) {</span>
<span class='hunk'>@@ -884,7 +881,7 @@ cons_show_account(ProfAccount *account)</span>
<span class='ctx'>                         wprintw(win, "\n");</span>
<span class='ctx'>                     }</span>
<span class='ctx'>                     if (caps-&gt;os != NULL) {</span>
<span class='del'>-                        console-&gt;print_time(console, '-');</span>
<span class='add'>+                        win_print_time(console, '-');</span>
<span class='ctx'>                         wprintw(win, "    OS: %s", caps-&gt;os);</span>
<span class='ctx'>                     }</span>
<span class='ctx'>                     if (caps-&gt;os_version != NULL) {</span>
<span class='hunk'>@@ -1357,7 +1354,7 @@ cons_show_contacts(GSList *list)</span>
<span class='ctx'>         PContact contact = curr-&gt;data;</span>
<span class='ctx'>         if ((strcmp(p_contact_subscription(contact), "to") == 0) ||</span>
<span class='ctx'>             (strcmp(p_contact_subscription(contact), "both") == 0)) {</span>
<span class='del'>-            console-&gt;show_contact(console, contact);</span>
<span class='add'>+            win_show_contact(console, contact);</span>
<span class='ctx'>         }</span>
<span class='ctx'>         curr = g_slist_next(curr);</span>
<span class='ctx'>     }</span>
<span class='hunk'>@@ -1378,47 +1375,47 @@ static void</span>
<span class='ctx'> _cons_splash_logo(void)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *console = wins_get_console();</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "Welcome to\n");</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, "                   ___            _           \n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, "                  / __)          (_)_         \n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, " ____   ____ ___ | |__ ____ ____  _| |_ _   _ \n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, "|  _ \\ / ___) _ \\|  __) _  |  _ \\| |  _) | | |\n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, "| | | | |  | |_| | | ( ( | | | | | | |_| |_| |\n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, "| ||_/|_|   \\___/|_|  \\_||_|_| |_|_|\\___)__  |\n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wattron(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'>     wprintw(console-&gt;win, "|_|                                    (____/ \n");</span>
<span class='ctx'>     wattroff(console-&gt;win, COLOUR_SPLASH);</span>
<span class='ctx'> </span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     wprintw(console-&gt;win, "\n");</span>
<span class='del'>-    console-&gt;print_time(console, '-');</span>
<span class='add'>+    win_print_time(console, '-');</span>
<span class='ctx'>     if (strcmp(PACKAGE_STATUS, "development") == 0) {</span>
<span class='ctx'> #ifdef HAVE_GIT_VERSION</span>
<span class='ctx'>         wprintw(console-&gt;win, "Version %sdev.%s.%s\n", PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);</span>
<span class='hunk'>@@ -1447,20 +1444,20 @@ _show_roster_contacts(GSList *list, gboolean show_groups)</span>
<span class='ctx'>         }</span>
<span class='ctx'> </span>
<span class='ctx'>         const char *presence = p_contact_presence(contact);</span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         if (p_contact_subscribed(contact)) {</span>
<span class='del'>-            console-&gt;presence_colour_on(console, presence);</span>
<span class='add'>+            win_presence_colour_on(console, presence);</span>
<span class='ctx'>             wprintw(console-&gt;win, "%s\n", title-&gt;str);</span>
<span class='del'>-            console-&gt;presence_colour_off(console, presence);</span>
<span class='add'>+            win_presence_colour_off(console, presence);</span>
<span class='ctx'>         } else {</span>
<span class='del'>-            console-&gt;presence_colour_on(console, "offline");</span>
<span class='add'>+            win_presence_colour_on(console, "offline");</span>
<span class='ctx'>             wprintw(console-&gt;win, "%s\n", title-&gt;str);</span>
<span class='del'>-            console-&gt;presence_colour_off(console, "offline");</span>
<span class='add'>+            win_presence_colour_off(console, "offline");</span>
<span class='ctx'>         }</span>
<span class='ctx'> </span>
<span class='ctx'>         g_string_free(title, TRUE);</span>
<span class='ctx'> </span>
<span class='del'>-        console-&gt;print_time(console, '-');</span>
<span class='add'>+        win_print_time(console, '-');</span>
<span class='ctx'>         wprintw(console-&gt;win, "    Subscription : ");</span>
<span class='ctx'>         GString *sub = g_string_new("");</span>
<span class='ctx'>         sub = g_string_append(sub, p_contact_subscription(contact));</span>
<span class='head'>diff --git a/src/ui/core.c b/src/ui/core.c
index a6c54faf..507cfb02 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/core.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/core.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/core.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/core.c</a>
</span><span class='hunk'>@@ -44,10 +44,10 @@</span>
<span class='ctx'> #include "config/preferences.h"</span>
<span class='ctx'> #include "config/theme.h"</span>
<span class='ctx'> #include "contact.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "jid.h"</span>
<span class='ctx'> #include "log.h"</span>
<span class='ctx'> #include "muc.h"</span>
<span class='del'>-#include "ui/notifier.h"</span>
<span class='ctx'> #include "ui/ui.h"</span>
<span class='ctx'> #include "ui/window.h"</span>
<span class='ctx'> #include "ui/windows.h"</span>
<span class='hunk'>@@ -63,11 +63,6 @@ static GTimer *ui_idle_time;</span>
<span class='ctx'> </span>
<span class='ctx'> static void _win_show_user(WINDOW *win, const char * const user, const int colour);</span>
<span class='ctx'> static void _win_show_message(WINDOW *win, const char * const message);</span>
<span class='del'>-static void _win_show_error_msg(WINDOW *win, const char * const message);</span>
<span class='del'>-static void _show_status_string(ProfWin *window, const char * const from,</span>
<span class='del'>-    const char * const show, const char * const status,</span>
<span class='del'>-    GDateTime *last_activity, const char * const pre,</span>
<span class='del'>-    const char * const default_show);</span>
<span class='ctx'> static void _win_handle_switch(const wint_t * const ch);</span>
<span class='ctx'> static void _win_handle_page(const wint_t * const ch);</span>
<span class='ctx'> static void _win_show_history(WINDOW *win, int win_index,</span>
<span class='hunk'>@@ -215,33 +210,11 @@ ui_contact_typing(const char * const barejid)</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-void</span>
<span class='del'>-ui_idle(void)</span>
<span class='add'>+GSList *</span>
<span class='add'>+ui_get_recipients(void)</span>
<span class='ctx'> {</span>
<span class='ctx'>     GSList *recipients = wins_get_chat_recipients();</span>
<span class='del'>-    GSList *curr = recipients;</span>
<span class='del'>-    while (curr != NULL) {</span>
<span class='del'>-        char *recipient = curr-&gt;data;</span>
<span class='del'>-        chat_session_no_activity(recipient);</span>
<span class='del'>-</span>
<span class='del'>-        if (chat_session_is_gone(recipient) &amp;&amp;</span>
<span class='del'>-                !chat_session_get_sent(recipient)) {</span>
<span class='del'>-            message_send_gone(recipient);</span>
<span class='del'>-        } else if (chat_session_is_inactive(recipient) &amp;&amp;</span>
<span class='del'>-                !chat_session_get_sent(recipient)) {</span>
<span class='del'>-            message_send_inactive(recipient);</span>
<span class='del'>-        } else if (prefs_get_boolean(PREF_OUTTYPE) &amp;&amp;</span>
<span class='del'>-                chat_session_is_paused(recipient) &amp;&amp;</span>
<span class='del'>-                !chat_session_get_sent(recipient)) {</span>
<span class='del'>-            message_send_paused(recipient);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        curr = g_slist_next(curr);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (recipients != NULL) {</span>
<span class='del'>-        g_slist_free(recipients);</span>
<span class='del'>-    }</span>
<span class='add'>+    return recipients;</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='hunk'>@@ -279,28 +252,7 @@ ui_incoming_msg(const char * const from, const char * const message,</span>
<span class='ctx'> </span>
<span class='ctx'>     // currently viewing chat window with sender</span>
<span class='ctx'>     if (wins_is_current(window)) {</span>
<span class='del'>-        if (tv_stamp == NULL) {</span>
<span class='del'>-            window-&gt;print_time(window, '-');</span>
<span class='del'>-        } else {</span>
<span class='del'>-            GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp);</span>
<span class='del'>-            gchar *date_fmt = g_date_time_format(time, "%H:%M:%S");</span>
<span class='del'>-            wattron(window-&gt;win, COLOUR_TIME);</span>
<span class='del'>-            wprintw(window-&gt;win, "%s - ", date_fmt);</span>
<span class='del'>-            wattroff(window-&gt;win, COLOUR_TIME);</span>
<span class='del'>-            g_date_time_unref(time);</span>
<span class='del'>-            g_free(date_fmt);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        if (strncmp(message, "/me ", 4) == 0) {</span>
<span class='del'>-            wattron(window-&gt;win, COLOUR_THEM);</span>
<span class='del'>-            wprintw(window-&gt;win, "*%s ", display_from);</span>
<span class='del'>-            waddstr(window-&gt;win, message + 4);</span>
<span class='del'>-            wprintw(window-&gt;win, "\n");</span>
<span class='del'>-            wattroff(window-&gt;win, COLOUR_THEM);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            _win_show_user(window-&gt;win, display_from, 1);</span>
<span class='del'>-            _win_show_message(window-&gt;win, message);</span>
<span class='del'>-        }</span>
<span class='add'>+        window-&gt;print_incoming_message(window, tv_stamp, display_from, message);</span>
<span class='ctx'>         title_bar_set_typing(FALSE);</span>
<span class='ctx'>         title_bar_draw();</span>
<span class='ctx'>         status_bar_active(num);</span>
<span class='hunk'>@@ -318,35 +270,15 @@ ui_incoming_msg(const char * const from, const char * const message,</span>
<span class='ctx'>             _win_show_history(window-&gt;win, num, from);</span>
<span class='ctx'>         }</span>
<span class='ctx'> </span>
<span class='del'>-        if (tv_stamp == NULL) {</span>
<span class='del'>-            window-&gt;print_time(window, '-');</span>
<span class='del'>-        } else {</span>
<span class='del'>-            // show users status first, when receiving message via delayed delivery</span>
<span class='del'>-            if (win_created) {</span>
<span class='del'>-                PContact pcontact = roster_get_contact(from);</span>
<span class='del'>-                if (pcontact != NULL) {</span>
<span class='del'>-                    window-&gt;show_contact(window, pcontact);</span>
<span class='del'>-                }</span>
<span class='add'>+        // show users status first, when receiving message via delayed delivery</span>
<span class='add'>+        if ((tv_stamp != NULL) &amp;&amp; (win_created)) {</span>
<span class='add'>+            PContact pcontact = roster_get_contact(from);</span>
<span class='add'>+            if (pcontact != NULL) {</span>
<span class='add'>+                win_show_contact(window, pcontact);</span>
<span class='ctx'>             }</span>
<span class='del'>-            GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp);</span>
<span class='del'>-            gchar *date_fmt = g_date_time_format(time, "%H:%M:%S");</span>
<span class='del'>-            wattron(window-&gt;win, COLOUR_TIME);</span>
<span class='del'>-            wprintw(window-&gt;win, "%s - ", date_fmt);</span>
<span class='del'>-            wattroff(window-&gt;win, COLOUR_TIME);</span>
<span class='del'>-            g_date_time_unref(time);</span>
<span class='del'>-            g_free(date_fmt);</span>
<span class='ctx'>         }</span>
<span class='ctx'> </span>
<span class='del'>-        if (strncmp(message, "/me ", 4) == 0) {</span>
<span class='del'>-            wattron(window-&gt;win, COLOUR_THEM);</span>
<span class='del'>-            wprintw(window-&gt;win, "*%s ", display_from);</span>
<span class='del'>-            waddstr(window-&gt;win, message + 4);</span>
<span class='del'>-            wprintw(window-&gt;win, "\n");</span>
<span class='del'>-            wattroff(window-&gt;win, COLOUR_THEM);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            _win_show_user(window-&gt;win, display_from, 1);</span>
<span class='del'>-            _win_show_message(window-&gt;win, message);</span>
<span class='del'>-        }</span>
<span class='add'>+        window-&gt;print_incoming_message(window, tv_stamp, display_from, message);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     int ui_index = num;</span>
<span class='hunk'>@@ -408,8 +340,8 @@ ui_handle_error_message(const char * const from, const char * const err_msg)</span>
<span class='ctx'>     if (err_msg == NULL) {</span>
<span class='ctx'>         cons_show_error("Unknown error received from service.");</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        ProfWin *win = wins_get_current();</span>
<span class='del'>-        gboolean handled = win-&gt;handle_error_message(win, from, err_msg);</span>
<span class='add'>+        ProfWin *current = wins_get_current();</span>
<span class='add'>+        gboolean handled = current-&gt;handle_error_message(current, from, err_msg);</span>
<span class='ctx'>         if (handled != TRUE) {</span>
<span class='ctx'>             cons_show_error("Error received from server: %s", err_msg);</span>
<span class='ctx'>         }</span>
<span class='hunk'>@@ -422,36 +354,20 @@ void</span>
<span class='ctx'> ui_contact_online(const char * const barejid, const char * const resource,</span>
<span class='ctx'>     const char * const show, const char * const status, GDateTime *last_activity)</span>
<span class='ctx'> {</span>
<span class='del'>-    Jid *jid = jid_create_from_bare_and_resource(barejid, resource);</span>
<span class='ctx'>     PContact contact = roster_get_contact(barejid);</span>
<span class='del'>-    GString *display_str = g_string_new("");</span>
<span class='del'>-</span>
<span class='del'>-    // use nickname if exists</span>
<span class='del'>-    if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-        g_string_append(display_str, p_contact_name(contact));</span>
<span class='del'>-    } else {</span>
<span class='del'>-        g_string_append(display_str, barejid);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // add resource if not default provided by profanity</span>
<span class='del'>-    if (strcmp(jid-&gt;resourcepart, "__prof_default") != 0) {</span>
<span class='del'>-        g_string_append(display_str, " (");</span>
<span class='del'>-        g_string_append(display_str, jid-&gt;resourcepart);</span>
<span class='del'>-        g_string_append(display_str, ")");</span>
<span class='del'>-    }</span>
<span class='add'>+    char *display_str = p_contact_create_display_string(contact, resource);</span>
<span class='ctx'> </span>
<span class='ctx'>     ProfWin *console = wins_get_console();</span>
<span class='del'>-    _show_status_string(console, display_str-&gt;str, show, status, last_activity,</span>
<span class='add'>+    win_show_status_string(console, display_str, show, status, last_activity,</span>
<span class='ctx'>         "++", "online");</span>
<span class='ctx'> </span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(barejid);</span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        _show_status_string(window, display_str-&gt;str, show, status,</span>
<span class='add'>+        win_show_status_string(window, display_str, show, status,</span>
<span class='ctx'>             last_activity, "++", "online");</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    jid_destroy(jid);</span>
<span class='del'>-    g_string_free(display_str, TRUE);</span>
<span class='add'>+    free(display_str);</span>
<span class='ctx'> </span>
<span class='ctx'>     if (wins_is_current(console)) {</span>
<span class='ctx'>         wins_refresh_current();</span>
<span class='hunk'>@@ -466,34 +382,20 @@ ui_contact_offline(const char * const from, const char * const show,</span>
<span class='ctx'> {</span>
<span class='ctx'>     Jid *jidp = jid_create(from);</span>
<span class='ctx'>     PContact contact = roster_get_contact(jidp-&gt;barejid);</span>
<span class='del'>-    GString *display_str = g_string_new("");</span>
<span class='del'>-</span>
<span class='del'>-    // use nickname if exists</span>
<span class='del'>-    if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-        g_string_append(display_str, p_contact_name(contact));</span>
<span class='del'>-    } else {</span>
<span class='del'>-        g_string_append(display_str, jidp-&gt;barejid);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // add resource if not default provided by profanity</span>
<span class='del'>-    if (strcmp(jidp-&gt;resourcepart, "__prof_default") != 0) {</span>
<span class='del'>-        g_string_append(display_str, " (");</span>
<span class='del'>-        g_string_append(display_str, jidp-&gt;resourcepart);</span>
<span class='del'>-        g_string_append(display_str, ")");</span>
<span class='del'>-    }</span>
<span class='add'>+    char *display_str = p_contact_create_display_string(contact, jidp-&gt;resourcepart);</span>
<span class='ctx'> </span>
<span class='ctx'>     ProfWin *console = wins_get_console();</span>
<span class='del'>-    _show_status_string(console, display_str-&gt;str, show, status, NULL, "--",</span>
<span class='add'>+    win_show_status_string(console, display_str, show, status, NULL, "--",</span>
<span class='ctx'>         "offline");</span>
<span class='ctx'> </span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(jidp-&gt;barejid);</span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        _show_status_string(window, display_str-&gt;str, show, status, NULL, "--",</span>
<span class='add'>+        win_show_status_string(window, display_str, show, status, NULL, "--",</span>
<span class='ctx'>             "offline");</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     jid_destroy(jidp);</span>
<span class='del'>-    g_string_free(display_str, TRUE);</span>
<span class='add'>+    free(display_str);</span>
<span class='ctx'> </span>
<span class='ctx'>     if (wins_is_current(console)) {</span>
<span class='ctx'>         wins_refresh_current();</span>
<span class='hunk'>@@ -824,39 +726,25 @@ ui_current_print_line(const char * const msg, ...)</span>
<span class='ctx'>     ProfWin *current = wins_get_current();</span>
<span class='ctx'>     va_list arg;</span>
<span class='ctx'>     va_start(arg, msg);</span>
<span class='del'>-    current-&gt;print_line(current, msg, arg);</span>
<span class='add'>+    win_print_line(current, '-', 0, msg, arg);</span>
<span class='ctx'>     va_end(arg);</span>
<span class='del'>-    current-&gt;refresh_win(current);</span>
<span class='add'>+    win_refresh(current);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='ctx'> ui_current_error_line(const char * const msg)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *current = wins_get_current();</span>
<span class='del'>-    current-&gt;print_time(current, '-');</span>
<span class='del'>-    wattron(current-&gt;win, COLOUR_ERROR);</span>
<span class='del'>-    wprintw(current-&gt;win, "%s\n", msg);</span>
<span class='del'>-    wattroff(current-&gt;win, COLOUR_ERROR);</span>
<span class='del'>-</span>
<span class='del'>-    wins_refresh_current();</span>
<span class='add'>+    win_print_line(current, '-', COLOUR_ERROR, msg);</span>
<span class='add'>+    win_refresh(current);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='ctx'> ui_current_page_off(void)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *current = wins_get_current();</span>
<span class='del'>-    current-&gt;paged = 0;</span>
<span class='del'>-</span>
<span class='del'>-    int rows = getmaxy(stdscr);</span>
<span class='del'>-    int y = getcury(current-&gt;win);</span>
<span class='del'>-    int size = rows - 3;</span>
<span class='del'>-</span>
<span class='del'>-    current-&gt;y_pos = y - (size - 1);</span>
<span class='del'>-    if (current-&gt;y_pos &lt; 0) {</span>
<span class='del'>-        current-&gt;y_pos = 0;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    wins_refresh_current();</span>
<span class='add'>+    win_page_off(current);</span>
<span class='add'>+    win_refresh(current);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='hunk'>@@ -867,8 +755,7 @@ ui_print_error_from_recipient(const char * const from, const char *err_msg)</span>
<span class='ctx'> </span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(from);</span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        window-&gt;print_time(window, '-');</span>
<span class='del'>-        _win_show_error_msg(window-&gt;win, err_msg);</span>
<span class='add'>+        win_print_line(window, '-', COLOUR_ERROR, "%s", err_msg);</span>
<span class='ctx'>         if (wins_is_current(window)) {</span>
<span class='ctx'>             wins_refresh_current();</span>
<span class='ctx'>         }</span>
<span class='hunk'>@@ -901,7 +788,7 @@ ui_print_system_msg_from_recipient(const char * const from, const char *message)</span>
<span class='ctx'>         }</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '-');</span>
<span class='add'>+    win_print_time(window, '-');</span>
<span class='ctx'>     wprintw(window-&gt;win, "*%s %s\n", bare_jid, message);</span>
<span class='ctx'> </span>
<span class='ctx'>     // this is the current window</span>
<span class='hunk'>@@ -926,12 +813,7 @@ ui_recipient_gone(const char * const barejid)</span>
<span class='ctx'> </span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(barejid);</span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        window-&gt;print_time(window, '!');</span>
<span class='del'>-        wattron(window-&gt;win, COLOUR_GONE);</span>
<span class='del'>-        wprintw(window-&gt;win, "&lt;- %s ", display_usr);</span>
<span class='del'>-        wprintw(window-&gt;win, "has left the conversation.");</span>
<span class='del'>-        wprintw(window-&gt;win, "\n");</span>
<span class='del'>-        wattroff(window-&gt;win, COLOUR_GONE);</span>
<span class='add'>+        win_print_line(window, '!', COLOUR_GONE, "&lt;- %s has left the conversation.", display_usr);</span>
<span class='ctx'>         if (wins_is_current(window)) {</span>
<span class='ctx'>             wins_refresh_current();</span>
<span class='ctx'>         }</span>
<span class='hunk'>@@ -967,7 +849,7 @@ ui_new_chat_win(const char * const to)</span>
<span class='ctx'>             if (strcmp(p_contact_presence(contact), "offline") == 0) {</span>
<span class='ctx'>                 const char * const show = p_contact_presence(contact);</span>
<span class='ctx'>                 const char * const status = p_contact_status(contact);</span>
<span class='del'>-                _show_status_string(window, to, show, status, NULL, "--", "offline");</span>
<span class='add'>+                win_show_status_string(window, to, show, status, NULL, "--", "offline");</span>
<span class='ctx'>             }</span>
<span class='ctx'>         }</span>
<span class='ctx'>     } else {</span>
<span class='hunk'>@@ -983,8 +865,7 @@ ui_create_duck_win(void)</span>
<span class='ctx'>     ProfWin *window = wins_new("DuckDuckGo search", WIN_DUCK);</span>
<span class='ctx'>     int num = wins_get_num(window);</span>
<span class='ctx'>     ui_switch_win(num);</span>
<span class='del'>-    window-&gt;print_time(window, '-');</span>
<span class='del'>-    wprintw(window-&gt;win, "Type ':help' to find out more.\n");</span>
<span class='add'>+    win_print_line(window, '-', 0, "Type ':help' to find out more.");</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='hunk'>@@ -1002,9 +883,9 @@ ui_duck(const char * const query)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient("DuckDuckGo search");</span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        window-&gt;print_time(window, '-');</span>
<span class='add'>+        win_print_time(window, '-');</span>
<span class='ctx'>         wprintw(window-&gt;win, "\n");</span>
<span class='del'>-        window-&gt;print_time(window, '-');</span>
<span class='add'>+        win_print_time(window, '-');</span>
<span class='ctx'>         wattron(window-&gt;win, COLOUR_ME);</span>
<span class='ctx'>         wprintw(window-&gt;win, "Query  : ");</span>
<span class='ctx'>         wattroff(window-&gt;win, COLOUR_ME);</span>
<span class='hunk'>@@ -1019,7 +900,7 @@ ui_duck_result(const char * const result)</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient("DuckDuckGo search");</span>
<span class='ctx'> </span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        window-&gt;print_time(window, '-');</span>
<span class='add'>+        win_print_time(window, '-');</span>
<span class='ctx'>         wattron(window-&gt;win, COLOUR_THEM);</span>
<span class='ctx'>         wprintw(window-&gt;win, "Result : ");</span>
<span class='ctx'>         wattroff(window-&gt;win, COLOUR_THEM);</span>
<span class='hunk'>@@ -1030,7 +911,7 @@ ui_duck_result(const char * const result)</span>
<span class='ctx'>             gunichar unichar = g_utf8_get_char(ptr);</span>
<span class='ctx'>             if (unichar == '\n') {</span>
<span class='ctx'>                 wprintw(window-&gt;win, "\n");</span>
<span class='del'>-                window-&gt;print_time(window, '-');</span>
<span class='add'>+                win_print_time(window, '-');</span>
<span class='ctx'>             } else {</span>
<span class='ctx'>                 gchar *string = g_ucs4_to_utf8(&amp;unichar, 1, NULL, NULL, NULL);</span>
<span class='ctx'>                 if (string != NULL) {</span>
<span class='hunk'>@@ -1075,7 +956,7 @@ ui_outgoing_msg(const char * const from, const char * const to,</span>
<span class='ctx'>             if (strcmp(p_contact_presence(contact), "offline") == 0) {</span>
<span class='ctx'>                 const char const *show = p_contact_presence(contact);</span>
<span class='ctx'>                 const char const *status = p_contact_status(contact);</span>
<span class='del'>-                _show_status_string(window, to, show, status, NULL, "--", "offline");</span>
<span class='add'>+                win_show_status_string(window, to, show, status, NULL, "--", "offline");</span>
<span class='ctx'>             }</span>
<span class='ctx'>         }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -1084,7 +965,7 @@ ui_outgoing_msg(const char * const from, const char * const to,</span>
<span class='ctx'>         num = wins_get_num(window);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '-');</span>
<span class='add'>+    win_print_time(window, '-');</span>
<span class='ctx'>     if (strncmp(message, "/me ", 4) == 0) {</span>
<span class='ctx'>         wattron(window-&gt;win, COLOUR_ME);</span>
<span class='ctx'>         wprintw(window-&gt;win, "*%s ", from);</span>
<span class='hunk'>@@ -1118,7 +999,7 @@ ui_room_roster(const char * const room, GList *roster, const char * const presen</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     if ((roster == NULL) || (g_list_length(roster) == 0)) {</span>
<span class='ctx'>         wattron(window-&gt;win, COLOUR_ROOMINFO);</span>
<span class='ctx'>         if (presence == NULL) {</span>
<span class='hunk'>@@ -1148,9 +1029,9 @@ ui_room_roster(const char * const room, GList *roster, const char * const presen</span>
<span class='ctx'>             const char const *nick = p_contact_barejid(member);</span>
<span class='ctx'>             const char const *show = p_contact_presence(member);</span>
<span class='ctx'> </span>
<span class='del'>-            window-&gt;presence_colour_on(window, show);</span>
<span class='add'>+            win_presence_colour_on(window, show);</span>
<span class='ctx'>             wprintw(window-&gt;win, "%s", nick);</span>
<span class='del'>-            window-&gt;presence_colour_off(window, show);</span>
<span class='add'>+            win_presence_colour_off(window, show);</span>
<span class='ctx'> </span>
<span class='ctx'>             if (roster-&gt;next != NULL) {</span>
<span class='ctx'>                 wprintw(window-&gt;win, ", ");</span>
<span class='hunk'>@@ -1173,7 +1054,7 @@ ui_room_member_offline(const char * const room, const char * const nick)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     wattron(window-&gt;win, COLOUR_OFFLINE);</span>
<span class='ctx'>     wprintw(window-&gt;win, "&lt;- %s has left the room.\n", nick);</span>
<span class='ctx'>     wattroff(window-&gt;win, COLOUR_OFFLINE);</span>
<span class='hunk'>@@ -1189,7 +1070,7 @@ ui_room_member_online(const char * const room, const char * const nick,</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     wattron(window-&gt;win, COLOUR_ONLINE);</span>
<span class='ctx'>     wprintw(window-&gt;win, "-&gt; %s has joined the room.\n", nick);</span>
<span class='ctx'>     wattroff(window-&gt;win, COLOUR_ONLINE);</span>
<span class='hunk'>@@ -1206,7 +1087,7 @@ ui_room_member_presence(const char * const room, const char * const nick,</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room);</span>
<span class='ctx'> </span>
<span class='ctx'>     if (window != NULL) {</span>
<span class='del'>-        _show_status_string(window, nick, show, status, NULL, "++", "online");</span>
<span class='add'>+        win_show_status_string(window, nick, show, status, NULL, "++", "online");</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     if (wins_is_current(window)) {</span>
<span class='hunk'>@@ -1220,7 +1101,7 @@ ui_room_member_nick_change(const char * const room,</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     wattron(window-&gt;win, COLOUR_THEM);</span>
<span class='ctx'>     wprintw(window-&gt;win, "** %s is now known as %s\n", old_nick, nick);</span>
<span class='ctx'>     wattroff(window-&gt;win, COLOUR_THEM);</span>
<span class='hunk'>@@ -1235,7 +1116,7 @@ ui_room_nick_change(const char * const room, const char * const nick)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     wattron(window-&gt;win, COLOUR_ME);</span>
<span class='ctx'>     wprintw(window-&gt;win, "** You are now known as %s\n", nick);</span>
<span class='ctx'>     wattroff(window-&gt;win, COLOUR_ME);</span>
<span class='hunk'>@@ -1278,7 +1159,7 @@ ui_room_message(const char * const room_jid, const char * const nick,</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room_jid);</span>
<span class='ctx'>     int num = wins_get_num(window);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '-');</span>
<span class='add'>+    win_print_time(window, '-');</span>
<span class='ctx'>     if (strcmp(nick, muc_get_room_nick(room_jid)) != 0) {</span>
<span class='ctx'>         if (strncmp(message, "/me ", 4) == 0) {</span>
<span class='ctx'>             wattron(window-&gt;win, COLOUR_THEM);</span>
<span class='hunk'>@@ -1349,7 +1230,7 @@ ui_room_subject(const char * const room_jid, const char * const subject)</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room_jid);</span>
<span class='ctx'>     int num = wins_get_num(window);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     wattron(window-&gt;win, COLOUR_ROOMINFO);</span>
<span class='ctx'>     wprintw(window-&gt;win, "Room subject: ");</span>
<span class='ctx'>     wattroff(window-&gt;win, COLOUR_ROOMINFO);</span>
<span class='hunk'>@@ -1372,7 +1253,7 @@ ui_room_broadcast(const char * const room_jid, const char * const message)</span>
<span class='ctx'>     ProfWin *window = wins_get_by_recipient(room_jid);</span>
<span class='ctx'>     int num = wins_get_num(window);</span>
<span class='ctx'> </span>
<span class='del'>-    window-&gt;print_time(window, '!');</span>
<span class='add'>+    win_print_time(window, '!');</span>
<span class='ctx'>     wattron(window-&gt;win, COLOUR_ROOMINFO);</span>
<span class='ctx'>     wprintw(window-&gt;win, "Room message: ");</span>
<span class='ctx'>     wattroff(window-&gt;win, COLOUR_ROOMINFO);</span>
<span class='hunk'>@@ -1397,9 +1278,9 @@ ui_status(void)</span>
<span class='ctx'>     ProfWin *current = wins_get_current();</span>
<span class='ctx'> </span>
<span class='ctx'>     if (pcontact != NULL) {</span>
<span class='del'>-        current-&gt;show_contact(current, pcontact);</span>
<span class='add'>+        win_show_contact(current, pcontact);</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        ui_current_print_line("Error getting contact info.");</span>
<span class='add'>+        win_print_line(current, '-', 0, "Error getting contact info.");</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -1411,9 +1292,9 @@ ui_status_private(void)</span>
<span class='ctx'>     ProfWin *current = wins_get_current();</span>
<span class='ctx'> </span>
<span class='ctx'>     if (pcontact != NULL) {</span>
<span class='del'>-        current-&gt;show_contact(current, pcontact);</span>
<span class='add'>+        win_show_contact(current, pcontact);</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        ui_current_print_line("Error getting contact info.");</span>
<span class='add'>+        win_print_line(current, '-', 0, "Error getting contact info.");</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     jid_destroy(jid);</span>
<span class='hunk'>@@ -1426,9 +1307,9 @@ ui_status_room(const char * const contact)</span>
<span class='ctx'>     ProfWin *current = wins_get_current();</span>
<span class='ctx'> </span>
<span class='ctx'>     if (pcontact != NULL) {</span>
<span class='del'>-        current-&gt;show_contact(current, pcontact);</span>
<span class='add'>+        win_show_contact(current, pcontact);</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        ui_current_print_line("No such participant \"%s\" in room.", contact);</span>
<span class='add'>+        win_print_line(current, '-', 0, "No such participant \"%s\" in room.", contact);</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -1478,12 +1359,17 @@ _ui_draw_win_title(void)</span>
<span class='ctx'>         gint unread = ui_unread();</span>
<span class='ctx'> </span>
<span class='ctx'>         if (unread != 0) {</span>
<span class='del'>-            snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s (%d) - %s%c", '\033', "Profanity", version_str-&gt;str, unread, jid, '\007');</span>
<span class='add'>+            snprintf(new_win_title, sizeof(new_win_title),</span>
<span class='add'>+                "%c]0;%s%s (%d) - %s%c", '\033', "Profanity", version_str-&gt;str,</span>
<span class='add'>+                unread, jid, '\007');</span>
<span class='ctx'>         } else {</span>
<span class='del'>-            snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s - %s%c", '\033', "Profanity", version_str-&gt;str, jid, '\007');</span>
<span class='add'>+            snprintf(new_win_title, sizeof(new_win_title),</span>
<span class='add'>+                "%c]0;%s%s - %s%c", '\033', "Profanity", version_str-&gt;str, jid,</span>
<span class='add'>+                '\007');</span>
<span class='ctx'>         }</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s%c", '\033', "Profanity", version_str-&gt;str, '\007');</span>
<span class='add'>+        snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s%c", '\033',</span>
<span class='add'>+            "Profanity", version_str-&gt;str, '\007');</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     g_string_free(version_str, TRUE);</span>
<span class='hunk'>@@ -1520,100 +1406,6 @@ _win_show_message(WINDOW *win, const char * const message)</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> static void</span>
<span class='del'>-_win_show_error_msg(WINDOW *win, const char * const message)</span>
<span class='del'>-{</span>
<span class='del'>-    wattron(win, COLOUR_ERROR);</span>
<span class='del'>-    wprintw(win, "%s\n", message);</span>
<span class='del'>-    wattroff(win, COLOUR_ERROR);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static void</span>
<span class='del'>-_show_status_string(ProfWin *window, const char * const from,</span>
<span class='del'>-    const char * const show, const char * const status,</span>
<span class='del'>-    GDateTime *last_activity, const char * const pre,</span>
<span class='del'>-    const char * const default_show)</span>
<span class='del'>-{</span>
<span class='del'>-    WINDOW *win = window-&gt;win;</span>
<span class='del'>-</span>
<span class='del'>-    if (!prefs_get_boolean(PREF_STATUSES))</span>
<span class='del'>-        return;</span>
<span class='del'>-</span>
<span class='del'>-    window-&gt;print_time(window, '-');</span>
<span class='del'>-</span>
<span class='del'>-    if (show != NULL) {</span>
<span class='del'>-        if (strcmp(show, "away") == 0) {</span>
<span class='del'>-            wattron(win, COLOUR_AWAY);</span>
<span class='del'>-        } else if (strcmp(show, "chat") == 0) {</span>
<span class='del'>-            wattron(win, COLOUR_CHAT);</span>
<span class='del'>-        } else if (strcmp(show, "dnd") == 0) {</span>
<span class='del'>-            wattron(win, COLOUR_DND);</span>
<span class='del'>-        } else if (strcmp(show, "xa") == 0) {</span>
<span class='del'>-            wattron(win, COLOUR_XA);</span>
<span class='del'>-        } else if (strcmp(show, "online") == 0) {</span>
<span class='del'>-            wattron(win, COLOUR_ONLINE);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            wattron(win, COLOUR_OFFLINE);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(default_show, "online") == 0) {</span>
<span class='del'>-        wattron(win, COLOUR_ONLINE);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        wattron(win, COLOUR_OFFLINE);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    wprintw(win, "%s %s", pre, from);</span>
<span class='del'>-</span>
<span class='del'>-    if (show != NULL)</span>
<span class='del'>-        wprintw(win, " is %s", show);</span>
<span class='del'>-    else</span>
<span class='del'>-        wprintw(win, " is %s", default_show);</span>
<span class='del'>-</span>
<span class='del'>-    if (last_activity != NULL) {</span>
<span class='del'>-        GDateTime *now = g_date_time_new_now_local();</span>
<span class='del'>-        GTimeSpan span = g_date_time_difference(now, last_activity);</span>
<span class='del'>-</span>
<span class='del'>-        wprintw(win, ", idle ");</span>
<span class='del'>-</span>
<span class='del'>-        int hours = span / G_TIME_SPAN_HOUR;</span>
<span class='del'>-        span = span - hours * G_TIME_SPAN_HOUR;</span>
<span class='del'>-        if (hours &gt; 0) {</span>
<span class='del'>-            wprintw(win, "%dh", hours);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        int minutes = span / G_TIME_SPAN_MINUTE;</span>
<span class='del'>-        span = span - minutes * G_TIME_SPAN_MINUTE;</span>
<span class='del'>-        wprintw(win, "%dm", minutes);</span>
<span class='del'>-</span>
<span class='del'>-        int seconds = span / G_TIME_SPAN_SECOND;</span>
<span class='del'>-        wprintw(win, "%ds", seconds);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    if (status != NULL)</span>
<span class='del'>-        wprintw(win, ", \"%s\"", status);</span>
<span class='del'>-</span>
<span class='del'>-    wprintw(win, "\n");</span>
<span class='del'>-</span>
<span class='del'>-    if (show != NULL) {</span>
<span class='del'>-        if (strcmp(show, "away") == 0) {</span>
<span class='del'>-            wattroff(win, COLOUR_AWAY);</span>
<span class='del'>-        } else if (strcmp(show, "chat") == 0) {</span>
<span class='del'>-            wattroff(win, COLOUR_CHAT);</span>
<span class='del'>-        } else if (strcmp(show, "dnd") == 0) {</span>
<span class='del'>-            wattroff(win, COLOUR_DND);</span>
<span class='del'>-        } else if (strcmp(show, "xa") == 0) {</span>
<span class='del'>-            wattroff(win, COLOUR_XA);</span>
<span class='del'>-        } else if (strcmp(show, "online") == 0) {</span>
<span class='del'>-            wattroff(win, COLOUR_ONLINE);</span>
<span class='del'>-        } else {</span>
<span class='del'>-            wattroff(win, COLOUR_OFFLINE);</span>
<span class='del'>-        }</span>
<span class='del'>-    } else if (strcmp(default_show, "online") == 0) {</span>
<span class='del'>-        wattroff(win, COLOUR_ONLINE);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        wattroff(win, COLOUR_OFFLINE);</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static void</span>
<span class='ctx'> _win_handle_switch(const wint_t * const ch)</span>
<span class='ctx'> {</span>
<span class='ctx'>     if (*ch == KEY_F(1)) {</span>
<span class='head'>diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c
index d5b882d7..3306a246 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/inputwin.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/inputwin.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/inputwin.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/inputwin.c</a>
</span><span class='hunk'>@@ -40,6 +40,7 @@</span>
<span class='ctx'> #include "config/theme.h"</span>
<span class='ctx'> #include "log.h"</span>
<span class='ctx'> #include "profanity.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "ui/ui.h"</span>
<span class='ctx'> #include "ui/windows.h"</span>
<span class='ctx'> #include "xmpp/xmpp.h"</span>
<span class='head'>diff --git a/src/ui/notifier.h b/src/ui/muc_window.c
index 9db789e8..72382032 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/notifier.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/notifier.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/muc_window.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/muc_window.c</a>
</span><span class='hunk'>@@ -1,5 +1,5 @@</span>
<span class='ctx'> /*</span>
<span class='del'>- * notifier.h</span>
<span class='add'>+ * muc_window.c</span>
<span class='ctx'>  *</span>
<span class='ctx'>  * Copyright (C) 2012, 2013 James Booth &lt;boothj5@gmail.com&gt;</span>
<span class='ctx'>  *</span>
<span class='hunk'>@@ -20,14 +20,20 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-void notifier_init(void);</span>
<span class='del'>-void notifier_uninit(void);</span>
<span class='add'>+#include &lt;glib.h&gt;</span>
<span class='ctx'> </span>
<span class='del'>-void notify_typing(const char * const handle);</span>
<span class='del'>-void notify_message(const char * const handle, int win);</span>
<span class='del'>-void notify_room_message(const char * const handle, const char * const room,</span>
<span class='del'>-    int win);</span>
<span class='del'>-void notify_remind(void);</span>
<span class='del'>-void notify_invite(const char * const from, const char * const room,</span>
<span class='del'>-    const char * const reason);</span>
<span class='del'>-void notify_subscription(const char * const from);</span>
<span class='add'>+#include "ui/window.h"</span>
<span class='add'>+</span>
<span class='add'>+gboolean</span>
<span class='add'>+muc_handle_error_message(ProfWin *self, const char * const from,</span>
<span class='add'>+    const char * const err_msg)</span>
<span class='add'>+{</span>
<span class='add'>+    gboolean handled = FALSE;</span>
<span class='add'>+    if (g_strcmp0(err_msg, "conflict") == 0) {</span>
<span class='add'>+        win_print_line(self, '-', 0, "Nickname already in use.");</span>
<span class='add'>+        win_refresh(self);</span>
<span class='add'>+        handled = TRUE;</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    return handled;</span>
<span class='add'>+}</span>
<span class='head'>diff --git a/src/ui/muc_window.h b/src/ui/muc_window.h
new file mode 100644
index 00000000..0b1f13ab
--- /dev/null
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/muc_window.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/muc_window.h</a>
</span><span class='hunk'>@@ -0,0 +1,33 @@</span>
<span class='add'>+/*</span>
<span class='add'>+ * muc_window.h</span>
<span class='add'>+ *</span>
<span class='add'>+ * Copyright (C) 2012, 2013 James Booth &lt;boothj5@gmail.com&gt;</span>
<span class='add'>+ *</span>
<span class='add'>+ * This file is part of Profanity.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is free software: you can redistribute it and/or modify</span>
<span class='add'>+ * it under the terms of the GNU General Public License as published by</span>
<span class='add'>+ * the Free Software Foundation, either version 3 of the License, or</span>
<span class='add'>+ * (at your option) any later version.</span>
<span class='add'>+ *</span>
<span class='add'>+ * Profanity is distributed in the hope that it will be useful,</span>
<span class='add'>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class='add'>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class='add'>+ * GNU General Public License for more details.</span>
<span class='add'>+ *</span>
<span class='add'>+ * You should have received a copy of the GNU General Public License</span>
<span class='add'>+ * along with Profanity.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class='add'>+ *</span>
<span class='add'>+ */</span>
<span class='add'>+</span>
<span class='add'>+#ifndef UI_MUC_WINDOW_H</span>
<span class='add'>+#define UI_MUC_WINDOW_H</span>
<span class='add'>+</span>
<span class='add'>+#include &lt;glib.h&gt;</span>
<span class='add'>+</span>
<span class='add'>+#include "ui/window.h"</span>
<span class='add'>+</span>
<span class='add'>+gboolean muc_handle_error_message(ProfWin *self, const char * const from,</span>
<span class='add'>+    const char * const err_msg);</span>
<span class='add'>+</span>
<span class='add'>+#endif</span>
<span class='head'>diff --git a/src/ui/ui.h b/src/ui/ui.h
index 1fa932b7..5ec4debd 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/ui.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/ui.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/ui.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/ui.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef UI_H</span>
<span class='del'>-#define UI_H</span>
<span class='add'>+#ifndef UI_UI_H</span>
<span class='add'>+#define UI_UI_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include "config.h"</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -48,7 +48,7 @@ void ui_refresh(void);</span>
<span class='ctx'> void ui_close(void);</span>
<span class='ctx'> void ui_resize(const int ch, const char * const input,</span>
<span class='ctx'>     const int size);</span>
<span class='del'>-void ui_idle(void);</span>
<span class='add'>+GSList* ui_get_recipients(void);</span>
<span class='ctx'> void ui_handle_special_keys(const wint_t * const ch, const char * const inp,</span>
<span class='ctx'>     const int size);</span>
<span class='ctx'> void ui_switch_win(const int i);</span>
<span class='hunk'>@@ -242,4 +242,17 @@ void inp_block(void);</span>
<span class='ctx'> void inp_get_password(char *passwd);</span>
<span class='ctx'> void inp_replace_input(char *input, const char * const new_input, int *size);</span>
<span class='ctx'> </span>
<span class='add'>+// desktop notifier actions</span>
<span class='add'>+void notifier_init(void);</span>
<span class='add'>+void notifier_uninit(void);</span>
<span class='add'>+</span>
<span class='add'>+void notify_typing(const char * const handle);</span>
<span class='add'>+void notify_message(const char * const handle, int win);</span>
<span class='add'>+void notify_room_message(const char * const handle, const char * const room,</span>
<span class='add'>+    int win);</span>
<span class='add'>+void notify_remind(void);</span>
<span class='add'>+void notify_invite(const char * const from, const char * const room,</span>
<span class='add'>+    const char * const reason);</span>
<span class='add'>+void notify_subscription(const char * const from);</span>
<span class='add'>+</span>
<span class='ctx'> #endif</span>
<span class='head'>diff --git a/src/ui/window.c b/src/ui/window.c
index 13956b22..135eac17 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/window.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/window.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/window.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/window.c</a>
</span><span class='hunk'>@@ -34,17 +34,12 @@</span>
<span class='ctx'> </span>
<span class='ctx'> #include "config/theme.h"</span>
<span class='ctx'> #include "ui/window.h"</span>
<span class='add'>+#include "ui/muc_window.h"</span>
<span class='ctx'> </span>
<span class='del'>-static gboolean _muc_handle_error_message(ProfWin *self, const char * const from,</span>
<span class='del'>-    const char * const err_msg);</span>
<span class='ctx'> static gboolean _default_handle_error_message(ProfWin *self, const char * const from,</span>
<span class='ctx'>     const char * const err_msg);</span>
<span class='del'>-static void _win_print_time(ProfWin *self, char show_char);</span>
<span class='del'>-static void _win_print_line(ProfWin *self, const char * const msg, ...);</span>
<span class='del'>-static void _win_refresh(ProfWin *self);</span>
<span class='del'>-static void _win_presence_colour_on(ProfWin *self, const char * const presence);</span>
<span class='del'>-static void _win_presence_colour_off(ProfWin *self, const char * const presence);</span>
<span class='del'>-static void _win_show_contact(ProfWin *self, PContact contact);</span>
<span class='add'>+static void _print_incoming_message(ProfWin *self, GTimeVal *tv_stamp,</span>
<span class='add'>+    const char * const from, const char * const message);</span>
<span class='ctx'> </span>
<span class='ctx'> ProfWin*</span>
<span class='ctx'> win_create(const char * const title, int cols, win_type_t type)</span>
<span class='hunk'>@@ -59,20 +54,31 @@ win_create(const char * const title, int cols, win_type_t type)</span>
<span class='ctx'>     new_win-&gt;history_shown = 0;</span>
<span class='ctx'>     new_win-&gt;type = type;</span>
<span class='ctx'> </span>
<span class='del'>-    new_win-&gt;print_time = _win_print_time;</span>
<span class='del'>-    new_win-&gt;print_line = _win_print_line;</span>
<span class='del'>-    new_win-&gt;refresh_win = _win_refresh;</span>
<span class='del'>-    new_win-&gt;presence_colour_on = _win_presence_colour_on;</span>
<span class='del'>-    new_win-&gt;presence_colour_off = _win_presence_colour_off;</span>
<span class='del'>-    new_win-&gt;show_contact = _win_show_contact;</span>
<span class='del'>-</span>
<span class='ctx'>     switch (new_win-&gt;type)</span>
<span class='ctx'>     {</span>
<span class='add'>+        case WIN_CONSOLE:</span>
<span class='add'>+            new_win-&gt;handle_error_message = _default_handle_error_message;</span>
<span class='add'>+            new_win-&gt;print_incoming_message = NULL;</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_CHAT:</span>
<span class='add'>+            new_win-&gt;handle_error_message = _default_handle_error_message;</span>
<span class='add'>+            new_win-&gt;print_incoming_message = _print_incoming_message;</span>
<span class='add'>+            break;</span>
<span class='ctx'>         case WIN_MUC:</span>
<span class='del'>-            new_win-&gt;handle_error_message = _muc_handle_error_message;</span>
<span class='add'>+            new_win-&gt;handle_error_message = muc_handle_error_message;</span>
<span class='add'>+            new_win-&gt;print_incoming_message = NULL;</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_PRIVATE:</span>
<span class='add'>+            new_win-&gt;handle_error_message = _default_handle_error_message;</span>
<span class='add'>+            new_win-&gt;print_incoming_message = _print_incoming_message;</span>
<span class='add'>+            break;</span>
<span class='add'>+        case WIN_DUCK:</span>
<span class='add'>+            new_win-&gt;handle_error_message = _default_handle_error_message;</span>
<span class='add'>+            new_win-&gt;print_incoming_message = NULL;</span>
<span class='ctx'>             break;</span>
<span class='ctx'>         default:</span>
<span class='ctx'>             new_win-&gt;handle_error_message = _default_handle_error_message;</span>
<span class='add'>+            new_win-&gt;print_incoming_message = NULL;</span>
<span class='ctx'>             break;</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -90,77 +96,95 @@ win_free(ProfWin* window)</span>
<span class='ctx'>     window = NULL;</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_win_print_time(ProfWin* self, char show_char)</span>
<span class='add'>+void</span>
<span class='add'>+win_print_time(ProfWin* window, char show_char)</span>
<span class='ctx'> {</span>
<span class='ctx'>     GDateTime *time = g_date_time_new_now_local();</span>
<span class='ctx'>     gchar *date_fmt = g_date_time_format(time, "%H:%M:%S");</span>
<span class='del'>-    wattron(self-&gt;win, COLOUR_TIME);</span>
<span class='del'>-    wprintw(self-&gt;win, "%s %c ", date_fmt, show_char);</span>
<span class='del'>-    wattroff(self-&gt;win, COLOUR_TIME);</span>
<span class='add'>+    wattron(window-&gt;win, COLOUR_TIME);</span>
<span class='add'>+    wprintw(window-&gt;win, "%s %c ", date_fmt, show_char);</span>
<span class='add'>+    wattroff(window-&gt;win, COLOUR_TIME);</span>
<span class='ctx'>     g_date_time_unref(time);</span>
<span class='ctx'>     g_free(date_fmt);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_win_print_line(ProfWin *self, const char * const msg, ...)</span>
<span class='add'>+void</span>
<span class='add'>+win_print_line(ProfWin *window, const char show_char, int attrs,</span>
<span class='add'>+    const char * const msg, ...)</span>
<span class='ctx'> {</span>
<span class='ctx'>     va_list arg;</span>
<span class='ctx'>     va_start(arg, msg);</span>
<span class='ctx'>     GString *fmt_msg = g_string_new(NULL);</span>
<span class='ctx'>     g_string_vprintf(fmt_msg, msg, arg);</span>
<span class='del'>-    _win_print_time(self, '-');</span>
<span class='del'>-    wprintw(self-&gt;win, "%s\n", fmt_msg-&gt;str);</span>
<span class='add'>+    win_print_time(window, show_char);</span>
<span class='add'>+    wattron(window-&gt;win, attrs);</span>
<span class='add'>+    wprintw(window-&gt;win, "%s\n", fmt_msg-&gt;str);</span>
<span class='add'>+    wattroff(window-&gt;win, attrs);</span>
<span class='ctx'>     g_string_free(fmt_msg, TRUE);</span>
<span class='ctx'>     va_end(arg);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_win_refresh(ProfWin *self)</span>
<span class='add'>+void</span>
<span class='add'>+win_refresh(ProfWin *window)</span>
<span class='ctx'> {</span>
<span class='ctx'>     int rows, cols;</span>
<span class='ctx'>     getmaxyx(stdscr, rows, cols);</span>
<span class='del'>-    prefresh(self-&gt;win, self-&gt;y_pos, 0, 1, 0, rows-3, cols-1);</span>
<span class='add'>+    prefresh(window-&gt;win, window-&gt;y_pos, 0, 1, 0, rows-3, cols-1);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_win_presence_colour_on(ProfWin *self, const char * const presence)</span>
<span class='add'>+void</span>
<span class='add'>+win_page_off(ProfWin *window)</span>
<span class='add'>+{</span>
<span class='add'>+    window-&gt;paged = 0;</span>
<span class='add'>+</span>
<span class='add'>+    int rows = getmaxy(stdscr);</span>
<span class='add'>+    int y = getcury(window-&gt;win);</span>
<span class='add'>+    int size = rows - 3;</span>
<span class='add'>+</span>
<span class='add'>+    window-&gt;y_pos = y - (size - 1);</span>
<span class='add'>+    if (window-&gt;y_pos &lt; 0) {</span>
<span class='add'>+        window-&gt;y_pos = 0;</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='add'>+</span>
<span class='add'>+void</span>
<span class='add'>+win_presence_colour_on(ProfWin *window, const char * const presence)</span>
<span class='ctx'> {</span>
<span class='ctx'>     if (g_strcmp0(presence, "online") == 0) {</span>
<span class='del'>-        wattron(self-&gt;win, COLOUR_ONLINE);</span>
<span class='add'>+        wattron(window-&gt;win, COLOUR_ONLINE);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "away") == 0) {</span>
<span class='del'>-        wattron(self-&gt;win, COLOUR_AWAY);</span>
<span class='add'>+        wattron(window-&gt;win, COLOUR_AWAY);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "chat") == 0) {</span>
<span class='del'>-        wattron(self-&gt;win, COLOUR_CHAT);</span>
<span class='add'>+        wattron(window-&gt;win, COLOUR_CHAT);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "dnd") == 0) {</span>
<span class='del'>-        wattron(self-&gt;win, COLOUR_DND);</span>
<span class='add'>+        wattron(window-&gt;win, COLOUR_DND);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "xa") == 0) {</span>
<span class='del'>-        wattron(self-&gt;win, COLOUR_XA);</span>
<span class='add'>+        wattron(window-&gt;win, COLOUR_XA);</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        wattron(self-&gt;win, COLOUR_OFFLINE);</span>
<span class='add'>+        wattron(window-&gt;win, COLOUR_OFFLINE);</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_win_presence_colour_off(ProfWin *self, const char * const presence)</span>
<span class='add'>+void</span>
<span class='add'>+win_presence_colour_off(ProfWin *window, const char * const presence)</span>
<span class='ctx'> {</span>
<span class='ctx'>     if (g_strcmp0(presence, "online") == 0) {</span>
<span class='del'>-        wattroff(self-&gt;win, COLOUR_ONLINE);</span>
<span class='add'>+        wattroff(window-&gt;win, COLOUR_ONLINE);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "away") == 0) {</span>
<span class='del'>-        wattroff(self-&gt;win, COLOUR_AWAY);</span>
<span class='add'>+        wattroff(window-&gt;win, COLOUR_AWAY);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "chat") == 0) {</span>
<span class='del'>-        wattroff(self-&gt;win, COLOUR_CHAT);</span>
<span class='add'>+        wattroff(window-&gt;win, COLOUR_CHAT);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "dnd") == 0) {</span>
<span class='del'>-        wattroff(self-&gt;win, COLOUR_DND);</span>
<span class='add'>+        wattroff(window-&gt;win, COLOUR_DND);</span>
<span class='ctx'>     } else if (g_strcmp0(presence, "xa") == 0) {</span>
<span class='del'>-        wattroff(self-&gt;win, COLOUR_XA);</span>
<span class='add'>+        wattroff(window-&gt;win, COLOUR_XA);</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        wattroff(self-&gt;win, COLOUR_OFFLINE);</span>
<span class='add'>+        wattroff(window-&gt;win, COLOUR_OFFLINE);</span>
<span class='ctx'>     }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_win_show_contact(ProfWin *self, PContact contact)</span>
<span class='add'>+void</span>
<span class='add'>+win_show_contact(ProfWin *window, PContact contact)</span>
<span class='ctx'> {</span>
<span class='ctx'>     const char *barejid = p_contact_barejid(contact);</span>
<span class='ctx'>     const char *name = p_contact_name(contact);</span>
<span class='hunk'>@@ -168,57 +192,126 @@ _win_show_contact(ProfWin *self, PContact contact)</span>
<span class='ctx'>     const char *status = p_contact_status(contact);</span>
<span class='ctx'>     GDateTime *last_activity = p_contact_last_activity(contact);</span>
<span class='ctx'> </span>
<span class='del'>-    _win_print_time(self, '-');</span>
<span class='del'>-    _win_presence_colour_on(self, presence);</span>
<span class='add'>+    win_print_time(window, '-');</span>
<span class='add'>+    win_presence_colour_on(window, presence);</span>
<span class='ctx'> </span>
<span class='ctx'>     if (name != NULL) {</span>
<span class='del'>-        wprintw(self-&gt;win, "%s", name);</span>
<span class='add'>+        wprintw(window-&gt;win, "%s", name);</span>
<span class='ctx'>     } else {</span>
<span class='del'>-        wprintw(self-&gt;win, "%s", barejid);</span>
<span class='add'>+        wprintw(window-&gt;win, "%s", barejid);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    wprintw(self-&gt;win, " is %s", presence);</span>
<span class='add'>+    wprintw(window-&gt;win, " is %s", presence);</span>
<span class='ctx'> </span>
<span class='ctx'>     if (last_activity != NULL) {</span>
<span class='ctx'>         GDateTime *now = g_date_time_new_now_local();</span>
<span class='ctx'>         GTimeSpan span = g_date_time_difference(now, last_activity);</span>
<span class='ctx'> </span>
<span class='del'>-        wprintw(self-&gt;win, ", idle ");</span>
<span class='add'>+        wprintw(window-&gt;win, ", idle ");</span>
<span class='ctx'> </span>
<span class='ctx'>         int hours = span / G_TIME_SPAN_HOUR;</span>
<span class='ctx'>         span = span - hours * G_TIME_SPAN_HOUR;</span>
<span class='ctx'>         if (hours &gt; 0) {</span>
<span class='del'>-            wprintw(self-&gt;win, "%dh", hours);</span>
<span class='add'>+            wprintw(window-&gt;win, "%dh", hours);</span>
<span class='ctx'>         }</span>
<span class='ctx'> </span>
<span class='ctx'>         int minutes = span / G_TIME_SPAN_MINUTE;</span>
<span class='ctx'>         span = span - minutes * G_TIME_SPAN_MINUTE;</span>
<span class='del'>-        wprintw(self-&gt;win, "%dm", minutes);</span>
<span class='add'>+        wprintw(window-&gt;win, "%dm", minutes);</span>
<span class='ctx'> </span>
<span class='ctx'>         int seconds = span / G_TIME_SPAN_SECOND;</span>
<span class='del'>-        wprintw(self-&gt;win, "%ds", seconds);</span>
<span class='add'>+        wprintw(window-&gt;win, "%ds", seconds);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='ctx'>     if (status != NULL) {</span>
<span class='del'>-        wprintw(self-&gt;win, ", \"%s\"", p_contact_status(contact));</span>
<span class='add'>+        wprintw(window-&gt;win, ", \"%s\"", p_contact_status(contact));</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    wprintw(self-&gt;win, "\n");</span>
<span class='del'>-    _win_presence_colour_off(self, presence);</span>
<span class='add'>+    wprintw(window-&gt;win, "\n");</span>
<span class='add'>+    win_presence_colour_off(window, presence);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static gboolean</span>
<span class='del'>-_muc_handle_error_message(ProfWin *self, const char * const from,</span>
<span class='del'>-    const char * const err_msg)</span>
<span class='add'>+void</span>
<span class='add'>+win_show_status_string(ProfWin *window, const char * const from,</span>
<span class='add'>+    const char * const show, const char * const status,</span>
<span class='add'>+    GDateTime *last_activity, const char * const pre,</span>
<span class='add'>+    const char * const default_show)</span>
<span class='ctx'> {</span>
<span class='del'>-    gboolean handled = FALSE;</span>
<span class='del'>-    if (g_strcmp0(err_msg, "conflict") == 0) {</span>
<span class='del'>-        _win_print_line(self, "Nickname already in use.");</span>
<span class='del'>-        _win_refresh(self);</span>
<span class='del'>-        handled = TRUE;</span>
<span class='add'>+    WINDOW *win = window-&gt;win;</span>
<span class='add'>+</span>
<span class='add'>+    win_print_time(window, '-');</span>
<span class='add'>+</span>
<span class='add'>+    if (show != NULL) {</span>
<span class='add'>+        if (strcmp(show, "away") == 0) {</span>
<span class='add'>+            wattron(win, COLOUR_AWAY);</span>
<span class='add'>+        } else if (strcmp(show, "chat") == 0) {</span>
<span class='add'>+            wattron(win, COLOUR_CHAT);</span>
<span class='add'>+        } else if (strcmp(show, "dnd") == 0) {</span>
<span class='add'>+            wattron(win, COLOUR_DND);</span>
<span class='add'>+        } else if (strcmp(show, "xa") == 0) {</span>
<span class='add'>+            wattron(win, COLOUR_XA);</span>
<span class='add'>+        } else if (strcmp(show, "online") == 0) {</span>
<span class='add'>+            wattron(win, COLOUR_ONLINE);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            wattron(win, COLOUR_OFFLINE);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(default_show, "online") == 0) {</span>
<span class='add'>+        wattron(win, COLOUR_ONLINE);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        wattron(win, COLOUR_OFFLINE);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    wprintw(win, "%s %s", pre, from);</span>
<span class='add'>+</span>
<span class='add'>+    if (show != NULL)</span>
<span class='add'>+        wprintw(win, " is %s", show);</span>
<span class='add'>+    else</span>
<span class='add'>+        wprintw(win, " is %s", default_show);</span>
<span class='add'>+</span>
<span class='add'>+    if (last_activity != NULL) {</span>
<span class='add'>+        GDateTime *now = g_date_time_new_now_local();</span>
<span class='add'>+        GTimeSpan span = g_date_time_difference(now, last_activity);</span>
<span class='add'>+</span>
<span class='add'>+        wprintw(win, ", idle ");</span>
<span class='add'>+</span>
<span class='add'>+        int hours = span / G_TIME_SPAN_HOUR;</span>
<span class='add'>+        span = span - hours * G_TIME_SPAN_HOUR;</span>
<span class='add'>+        if (hours &gt; 0) {</span>
<span class='add'>+            wprintw(win, "%dh", hours);</span>
<span class='add'>+        }</span>
<span class='add'>+</span>
<span class='add'>+        int minutes = span / G_TIME_SPAN_MINUTE;</span>
<span class='add'>+        span = span - minutes * G_TIME_SPAN_MINUTE;</span>
<span class='add'>+        wprintw(win, "%dm", minutes);</span>
<span class='add'>+</span>
<span class='add'>+        int seconds = span / G_TIME_SPAN_SECOND;</span>
<span class='add'>+        wprintw(win, "%ds", seconds);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    return handled;</span>
<span class='add'>+    if (status != NULL)</span>
<span class='add'>+        wprintw(win, ", \"%s\"", status);</span>
<span class='add'>+</span>
<span class='add'>+    wprintw(win, "\n");</span>
<span class='add'>+</span>
<span class='add'>+    if (show != NULL) {</span>
<span class='add'>+        if (strcmp(show, "away") == 0) {</span>
<span class='add'>+            wattroff(win, COLOUR_AWAY);</span>
<span class='add'>+        } else if (strcmp(show, "chat") == 0) {</span>
<span class='add'>+            wattroff(win, COLOUR_CHAT);</span>
<span class='add'>+        } else if (strcmp(show, "dnd") == 0) {</span>
<span class='add'>+            wattroff(win, COLOUR_DND);</span>
<span class='add'>+        } else if (strcmp(show, "xa") == 0) {</span>
<span class='add'>+            wattroff(win, COLOUR_XA);</span>
<span class='add'>+        } else if (strcmp(show, "online") == 0) {</span>
<span class='add'>+            wattroff(win, COLOUR_ONLINE);</span>
<span class='add'>+        } else {</span>
<span class='add'>+            wattroff(win, COLOUR_OFFLINE);</span>
<span class='add'>+        }</span>
<span class='add'>+    } else if (strcmp(default_show, "online") == 0) {</span>
<span class='add'>+        wattroff(win, COLOUR_ONLINE);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        wattroff(win, COLOUR_OFFLINE);</span>
<span class='add'>+    }</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> static gboolean</span>
<span class='hunk'>@@ -227,3 +320,34 @@ _default_handle_error_message(ProfWin *self, const char * const from,</span>
<span class='ctx'> {</span>
<span class='ctx'>     return FALSE;</span>
<span class='ctx'> }</span>
<span class='add'>+</span>
<span class='add'>+static void</span>
<span class='add'>+_print_incoming_message(ProfWin *self, GTimeVal *tv_stamp,</span>
<span class='add'>+    const char * const from, const char * const message)</span>
<span class='add'>+{</span>
<span class='add'>+    if (tv_stamp == NULL) {</span>
<span class='add'>+        win_print_time(self, '-');</span>
<span class='add'>+    } else {</span>
<span class='add'>+        GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp);</span>
<span class='add'>+        gchar *date_fmt = g_date_time_format(time, "%H:%M:%S");</span>
<span class='add'>+        wattron(self-&gt;win, COLOUR_TIME);</span>
<span class='add'>+        wprintw(self-&gt;win, "%s - ", date_fmt);</span>
<span class='add'>+        wattroff(self-&gt;win, COLOUR_TIME);</span>
<span class='add'>+        g_date_time_unref(time);</span>
<span class='add'>+        g_free(date_fmt);</span>
<span class='add'>+    }</span>
<span class='add'>+</span>
<span class='add'>+    if (strncmp(message, "/me ", 4) == 0) {</span>
<span class='add'>+        wattron(self-&gt;win, COLOUR_THEM);</span>
<span class='add'>+        wprintw(self-&gt;win, "*%s ", from);</span>
<span class='add'>+        waddstr(self-&gt;win, message + 4);</span>
<span class='add'>+        wprintw(self-&gt;win, "\n");</span>
<span class='add'>+        wattroff(self-&gt;win, COLOUR_THEM);</span>
<span class='add'>+    } else {</span>
<span class='add'>+        wattron(self-&gt;win, COLOUR_THEM);</span>
<span class='add'>+        wprintw(self-&gt;win, "%s: ", from);</span>
<span class='add'>+        wattroff(self-&gt;win, COLOUR_THEM);</span>
<span class='add'>+        waddstr(self-&gt;win, message);</span>
<span class='add'>+        wprintw(self-&gt;win, "\n");</span>
<span class='add'>+    }</span>
<span class='add'>+}</span>
<span class='head'>diff --git a/src/ui/window.h b/src/ui/window.h
index 2eec3b01..69e446fa 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/window.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/window.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/window.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/window.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef WINDOW_H</span>
<span class='del'>-#define WINDOW_H</span>
<span class='add'>+#ifndef UI_WINDOW_H</span>
<span class='add'>+#define UI_WINDOW_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include "config.h"</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -52,17 +52,25 @@ typedef struct prof_win_t {</span>
<span class='ctx'>     int paged;</span>
<span class='ctx'>     int unread;</span>
<span class='ctx'>     int history_shown;</span>
<span class='del'>-    void (*print_time)(struct prof_win_t *self, char show_char);</span>
<span class='del'>-    void (*print_line)(struct prof_win_t *self, const char * const msg, ...);</span>
<span class='del'>-    void (*refresh_win)(struct prof_win_t *self);</span>
<span class='del'>-    void (*presence_colour_on)(struct prof_win_t *self, const char * const presence);</span>
<span class='del'>-    void (*presence_colour_off)(struct prof_win_t *self, const char * const presence);</span>
<span class='del'>-    void (*show_contact)(struct prof_win_t *self, PContact contact);</span>
<span class='ctx'>     gboolean (*handle_error_message)(struct prof_win_t *self,</span>
<span class='ctx'>         const char * const from, const char * const err_msg);</span>
<span class='add'>+    void (*print_incoming_message)(struct prof_win_t *self, GTimeVal *tv_stamp,</span>
<span class='add'>+        const char * const from, const char * const message);</span>
<span class='ctx'> } ProfWin;</span>
<span class='ctx'> </span>
<span class='ctx'> ProfWin* win_create(const char * const title, int cols, win_type_t type);</span>
<span class='ctx'> void win_free(ProfWin *window);</span>
<span class='add'>+void win_print_line(ProfWin *self, const char show_char, int attrs,</span>
<span class='add'>+    const char * const msg, ...);</span>
<span class='add'>+void win_refresh(ProfWin *window);</span>
<span class='add'>+void win_page_off(ProfWin *window);</span>
<span class='add'>+void win_print_time(ProfWin *window, char show_char);</span>
<span class='add'>+void win_presence_colour_on(ProfWin *window, const char * const presence);</span>
<span class='add'>+void win_presence_colour_off(ProfWin *window, const char * const presence);</span>
<span class='add'>+void win_show_contact(ProfWin *window, PContact contact);</span>
<span class='add'>+void win_show_status_string(ProfWin *window, const char * const from,</span>
<span class='add'>+    const char * const show, const char * const status,</span>
<span class='add'>+    GDateTime *last_activity, const char * const pre,</span>
<span class='add'>+    const char * const default_show);</span>
<span class='ctx'> </span>
<span class='ctx'> #endif</span>
<span class='head'>diff --git a/src/ui/windows.c b/src/ui/windows.c
index 0d9d7048..001f1bfc 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/windows.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/windows.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/windows.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/windows.c</a>
</span><span class='hunk'>@@ -33,6 +33,7 @@</span>
<span class='ctx'> #endif</span>
<span class='ctx'> </span>
<span class='ctx'> #include "common.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "config/theme.h"</span>
<span class='ctx'> #include "ui/ui.h"</span>
<span class='ctx'> #include "ui/window.h"</span>
<span class='hunk'>@@ -207,9 +208,7 @@ void</span>
<span class='ctx'> wins_refresh_current(void)</span>
<span class='ctx'> {</span>
<span class='ctx'>     ProfWin *window = wins_get_current();</span>
<span class='del'>-    int rows, cols;</span>
<span class='del'>-    getmaxyx(stdscr, rows, cols);</span>
<span class='del'>-    prefresh(window-&gt;win, window-&gt;y_pos, 0, 1, 0, rows-3, cols-1);</span>
<span class='add'>+    win_refresh(window);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='hunk'>@@ -350,7 +349,7 @@ wins_lost_connection(void)</span>
<span class='ctx'>     while (curr != NULL) {</span>
<span class='ctx'>         ProfWin *window = curr-&gt;data;</span>
<span class='ctx'>         if (window-&gt;type != WIN_CONSOLE) {</span>
<span class='del'>-            window-&gt;print_time(window, '-');</span>
<span class='add'>+            win_print_time(window, '-');</span>
<span class='ctx'>             wattron(window-&gt;win, COLOUR_ERROR);</span>
<span class='ctx'>             wprintw(window-&gt;win, "%s\n", "Lost connection.");</span>
<span class='ctx'>             wattroff(window-&gt;win, COLOUR_ERROR);</span>
<span class='head'>diff --git a/src/ui/windows.h b/src/ui/windows.h
index 3cf593e8..4467e507 100644
--- a/<a href='/danisanti/profani-tty/tree/src/ui/windows.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/ui/windows.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/ui/windows.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/ui/windows.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef WINDOWS_H</span>
<span class='del'>-#define WINDOWS_H</span>
<span class='add'>+#ifndef UI_WINDOWS_H</span>
<span class='add'>+#define UI_WINDOWS_H</span>
<span class='ctx'> </span>
<span class='ctx'> void wins_init(void);</span>
<span class='ctx'> ProfWin * wins_get_console(void);</span>
<span class='head'>diff --git a/src/xmpp/bookmark.h b/src/xmpp/bookmark.h
index e15b6eab..8b5418b0 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/bookmark.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/bookmark.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/bookmark.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/bookmark.h</a>
</span><span class='hunk'>@@ -1,6 +1,6 @@</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef BOOKMARK_H</span>
<span class='del'>-#define BOOKMARK_H</span>
<span class='add'>+#ifndef XMPP_BOOKMARK_H</span>
<span class='add'>+#define XMPP_BOOKMARK_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include &lt;glib.h&gt;</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -13,10 +13,5 @@ struct bookmark_t {</span>
<span class='ctx'> typedef struct bookmark_t Bookmark;</span>
<span class='ctx'> </span>
<span class='ctx'> void bookmark_request(void);</span>
<span class='del'>-void bookmark_add(const char *jid, const char *nick, gboolean autojoin);</span>
<span class='del'>-void bookmark_remove(const char *jid, gboolean autojoin);</span>
<span class='del'>-const GList *bookmark_get_list(void);</span>
<span class='del'>-char *bookmark_find(char *search_str);</span>
<span class='del'>-void bookmark_autocomplete_reset(void);</span>
<span class='ctx'> </span>
<span class='ctx'> #endif</span>
<span class='head'>diff --git a/src/xmpp/capabilities.h b/src/xmpp/capabilities.h
index d97b84b2..45d97e0f 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/capabilities.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/capabilities.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/capabilities.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/capabilities.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef CAPABILITIES_H</span>
<span class='del'>-#define CAPABILITIES_H</span>
<span class='add'>+#ifndef XMPP_CAPABILITIES_H</span>
<span class='add'>+#define XMPP_CAPABILITIES_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include &lt;strophe.h&gt;</span>
<span class='ctx'> </span>
<span class='head'>diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h
index b5701252..f11bc8c8 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/connection.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/connection.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/connection.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/connection.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef CONNECTION_H</span>
<span class='del'>-#define CONNECTION_H</span>
<span class='add'>+#ifndef XMPP_CONNECTION_H</span>
<span class='add'>+#define XMPP_CONNECTION_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include &lt;strophe.h&gt;</span>
<span class='ctx'> </span>
<span class='head'>diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 1ddfcb34..fdabe771 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/iq.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/iq.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/iq.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/iq.c</a>
</span><span class='hunk'>@@ -38,6 +38,7 @@</span>
<span class='ctx'> #include "xmpp/capabilities.h"</span>
<span class='ctx'> #include "xmpp/connection.h"</span>
<span class='ctx'> #include "xmpp/stanza.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "xmpp/xmpp.h"</span>
<span class='ctx'> </span>
<span class='ctx'> #define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_IQ, type, ctx)</span>
<span class='head'>diff --git a/src/xmpp/iq.h b/src/xmpp/iq.h
index 86966e26..64844228 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/iq.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/iq.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/iq.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/iq.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef IQ_H</span>
<span class='del'>-#define IQ_H</span>
<span class='add'>+#ifndef XMPP_IQ_H</span>
<span class='add'>+#define XMPP_IQ_H</span>
<span class='ctx'> </span>
<span class='ctx'> void iq_add_handlers(void);</span>
<span class='ctx'> void iq_roster_request(void);</span>
<span class='head'>diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index 8a977490..a1644587 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/message.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/message.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/message.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/message.c</a>
</span><span class='hunk'>@@ -33,6 +33,7 @@</span>
<span class='ctx'> #include "xmpp/connection.h"</span>
<span class='ctx'> #include "xmpp/message.h"</span>
<span class='ctx'> #include "xmpp/roster.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "xmpp/stanza.h"</span>
<span class='ctx'> #include "xmpp/xmpp.h"</span>
<span class='ctx'> </span>
<span class='head'>diff --git a/src/xmpp/message.h b/src/xmpp/message.h
index 639ae558..3bfa60ef 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/message.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/message.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/message.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/message.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef MESSAGE_H</span>
<span class='del'>-#define MESSAGE_H</span>
<span class='add'>+#ifndef XMPP_MESSAGE_H</span>
<span class='add'>+#define XMPP_MESSAGE_H</span>
<span class='ctx'> </span>
<span class='ctx'> void message_add_handlers(void);</span>
<span class='ctx'> </span>
<span class='head'>diff --git a/src/xmpp/presence.h b/src/xmpp/presence.h
index fa63d78e..fb13a699 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/presence.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/presence.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/presence.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/presence.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef PRESENCE_H</span>
<span class='del'>-#define PRESENCE_H</span>
<span class='add'>+#ifndef XMPP_PRESENCE_H</span>
<span class='add'>+#define XMPP_PRESENCE_H</span>
<span class='ctx'> </span>
<span class='ctx'> void presence_sub_requests_init(void);</span>
<span class='ctx'> void presence_add_handlers(void);</span>
<span class='head'>diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c
index 5fbb7be7..51c34ea1 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/roster.c?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/roster.c</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/roster.c?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/roster.c</a>
</span><span class='hunk'>@@ -32,30 +32,13 @@</span>
<span class='ctx'> #include "tools/autocomplete.h"</span>
<span class='ctx'> #include "xmpp/connection.h"</span>
<span class='ctx'> #include "xmpp/roster.h"</span>
<span class='add'>+#include "roster_list.h"</span>
<span class='ctx'> #include "xmpp/stanza.h"</span>
<span class='ctx'> #include "xmpp/xmpp.h"</span>
<span class='ctx'> </span>
<span class='ctx'> #define HANDLE(type, func) xmpp_handler_add(conn, func, XMPP_NS_ROSTER, \</span>
<span class='ctx'> STANZA_NAME_IQ, type, ctx)</span>
<span class='ctx'> </span>
<span class='del'>-// nicknames</span>
<span class='del'>-static Autocomplete name_ac;</span>
<span class='del'>-</span>
<span class='del'>-// barejids</span>
<span class='del'>-static Autocomplete barejid_ac;</span>
<span class='del'>-</span>
<span class='del'>-// fulljids</span>
<span class='del'>-static Autocomplete fulljid_ac;</span>
<span class='del'>-</span>
<span class='del'>-// groups</span>
<span class='del'>-static Autocomplete groups_ac;</span>
<span class='del'>-</span>
<span class='del'>-// contacts, indexed on barejid</span>
<span class='del'>-static GHashTable *contacts;</span>
<span class='del'>-</span>
<span class='del'>-// nickname to jid map</span>
<span class='del'>-static GHashTable *name_to_barejid;</span>
<span class='del'>-</span>
<span class='ctx'> // callback data for group commands</span>
<span class='ctx'> typedef struct _group_data {</span>
<span class='ctx'>     char *name;</span>
<span class='hunk'>@@ -77,14 +60,7 @@ _group_remove_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,</span>
<span class='ctx'>     void * const userdata);</span>
<span class='ctx'> </span>
<span class='ctx'> // helper functions</span>
<span class='del'>-static void _add_name_and_barejid(const char * const name,</span>
<span class='del'>-    const char * const barejid);</span>
<span class='del'>-static void _replace_name(const char * const current_name,</span>
<span class='del'>-    const char * const new_name, const char * const barejid);</span>
<span class='ctx'> GSList * _get_groups_from_item(xmpp_stanza_t *item);</span>
<span class='del'>-static gboolean _key_equals(void *key1, void *key2);</span>
<span class='del'>-static gboolean _datetimes_equal(GDateTime *dt1, GDateTime *dt2);</span>
<span class='del'>-static gint _compare_contacts(PContact a, PContact b);</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='ctx'> roster_add_handlers(void)</span>
<span class='hunk'>@@ -106,52 +82,6 @@ roster_request(void)</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='del'>-roster_init(void)</span>
<span class='del'>-{</span>
<span class='del'>-    name_ac = autocomplete_new();</span>
<span class='del'>-    barejid_ac = autocomplete_new();</span>
<span class='del'>-    fulljid_ac = autocomplete_new();</span>
<span class='del'>-    groups_ac = autocomplete_new();</span>
<span class='del'>-    contacts = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, g_free,</span>
<span class='del'>-        (GDestroyNotify)p_contact_free);</span>
<span class='del'>-    name_to_barejid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,</span>
<span class='del'>-        g_free);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-void</span>
<span class='del'>-roster_clear(void)</span>
<span class='del'>-{</span>
<span class='del'>-    autocomplete_clear(name_ac);</span>
<span class='del'>-    autocomplete_clear(barejid_ac);</span>
<span class='del'>-    autocomplete_clear(fulljid_ac);</span>
<span class='del'>-    autocomplete_clear(groups_ac);</span>
<span class='del'>-    g_hash_table_destroy(contacts);</span>
<span class='del'>-    contacts = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, g_free,</span>
<span class='del'>-        (GDestroyNotify)p_contact_free);</span>
<span class='del'>-    g_hash_table_destroy(name_to_barejid);</span>
<span class='del'>-    name_to_barejid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,</span>
<span class='del'>-        g_free);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-void</span>
<span class='del'>-roster_free()</span>
<span class='del'>-{</span>
<span class='del'>-    autocomplete_free(name_ac);</span>
<span class='del'>-    autocomplete_free(barejid_ac);</span>
<span class='del'>-    autocomplete_free(fulljid_ac);</span>
<span class='del'>-    autocomplete_free(groups_ac);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-void</span>
<span class='del'>-roster_reset_search_attempts(void)</span>
<span class='del'>-{</span>
<span class='del'>-    autocomplete_reset(name_ac);</span>
<span class='del'>-    autocomplete_reset(barejid_ac);</span>
<span class='del'>-    autocomplete_reset(fulljid_ac);</span>
<span class='del'>-    autocomplete_reset(groups_ac);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-void</span>
<span class='ctx'> roster_add_new(const char * const barejid, const char * const name)</span>
<span class='ctx'> {</span>
<span class='ctx'>     xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='hunk'>@@ -162,7 +92,7 @@ roster_add_new(const char * const barejid, const char * const name)</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='del'>-roster_remove(const char * const barejid)</span>
<span class='add'>+roster_send_remove(const char * const barejid)</span>
<span class='ctx'> {</span>
<span class='ctx'>     xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='ctx'>     xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='hunk'>@@ -171,180 +101,46 @@ roster_remove(const char * const barejid)</span>
<span class='ctx'>     xmpp_stanza_release(iq);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-gboolean</span>
<span class='del'>-roster_add(const char * const barejid, const char * const name, GSList *groups,</span>
<span class='del'>-    const char * const subscription, gboolean pending_out, gboolean from_initial)</span>
<span class='del'>-{</span>
<span class='del'>-    gboolean added = FALSE;</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-</span>
<span class='del'>-    if (contact == NULL) {</span>
<span class='del'>-        contact = p_contact_new(barejid, name, groups, subscription, NULL,</span>
<span class='del'>-            pending_out);</span>
<span class='del'>-</span>
<span class='del'>-        // add groups</span>
<span class='del'>-        while (groups != NULL) {</span>
<span class='del'>-            autocomplete_add(groups_ac, groups-&gt;data);</span>
<span class='del'>-            groups = g_slist_next(groups);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        g_hash_table_insert(contacts, strdup(barejid), contact);</span>
<span class='del'>-        autocomplete_add(barejid_ac, barejid);</span>
<span class='del'>-        _add_name_and_barejid(name, barejid);</span>
<span class='del'>-</span>
<span class='del'>-        if (!from_initial) {</span>
<span class='del'>-            prof_handle_roster_add(barejid, name);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        added = TRUE;</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return added;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='ctx'> void</span>
<span class='del'>-roster_update(const char * const barejid, const char * const name,</span>
<span class='del'>-    GSList *groups, const char * const subscription, gboolean pending_out)</span>
<span class='del'>-{</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-</span>
<span class='del'>-    if (contact == NULL) {</span>
<span class='del'>-        roster_add(barejid, name, groups, subscription, pending_out, FALSE);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        p_contact_set_subscription(contact, subscription);</span>
<span class='del'>-        p_contact_set_pending_out(contact, pending_out);</span>
<span class='del'>-</span>
<span class='del'>-        const char * const new_name = name;</span>
<span class='del'>-        const char * current_name = NULL;</span>
<span class='del'>-        if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-            current_name = strdup(p_contact_name(contact));</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        p_contact_set_name(contact, new_name);</span>
<span class='del'>-        p_contact_set_groups(contact, groups);</span>
<span class='del'>-        _replace_name(current_name, new_name, barejid);</span>
<span class='del'>-</span>
<span class='del'>-        // add groups</span>
<span class='del'>-        while (groups != NULL) {</span>
<span class='del'>-            autocomplete_add(groups_ac, groups-&gt;data);</span>
<span class='del'>-            groups = g_slist_next(groups);</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-gboolean</span>
<span class='del'>-roster_update_presence(const char * const barejid, Resource *resource,</span>
<span class='del'>-    GDateTime *last_activity)</span>
<span class='add'>+roster_send_name_change(const char * const barejid, const char * const new_name, GSList *groups)</span>
<span class='ctx'> {</span>
<span class='del'>-    assert(barejid != NULL);</span>
<span class='del'>-    assert(resource != NULL);</span>
<span class='del'>-</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-    if (contact == NULL) {</span>
<span class='del'>-        return FALSE;</span>
<span class='del'>-    }</span>
<span class='del'>-    if (!_datetimes_equal(p_contact_last_activity(contact), last_activity)) {</span>
<span class='del'>-        p_contact_set_last_activity(contact, last_activity);</span>
<span class='del'>-    }</span>
<span class='del'>-    p_contact_set_presence(contact, resource);</span>
<span class='del'>-    Jid *jid = jid_create_from_bare_and_resource(barejid, resource-&gt;name);</span>
<span class='del'>-    autocomplete_add(fulljid_ac, jid-&gt;fulljid);</span>
<span class='del'>-    jid_destroy(jid);</span>
<span class='del'>-</span>
<span class='del'>-    return TRUE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-gboolean</span>
<span class='del'>-roster_contact_offline(const char * const barejid,</span>
<span class='del'>-    const char * const resource, const char * const status)</span>
<span class='del'>-{</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-</span>
<span class='del'>-    if (contact == NULL) {</span>
<span class='del'>-        return FALSE;</span>
<span class='del'>-    }</span>
<span class='del'>-    if (resource == NULL) {</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    } else {</span>
<span class='del'>-        gboolean result = p_contact_remove_resource(contact, resource);</span>
<span class='del'>-        if (result == TRUE) {</span>
<span class='del'>-            Jid *jid = jid_create_from_bare_and_resource(barejid, resource);</span>
<span class='del'>-            autocomplete_remove(fulljid_ac, jid-&gt;fulljid);</span>
<span class='del'>-            jid_destroy(jid);</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        return result;</span>
<span class='del'>-    }</span>
<span class='add'>+    xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='add'>+    xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='add'>+    xmpp_stanza_t *iq = stanza_create_roster_set(ctx, NULL, barejid, new_name,</span>
<span class='add'>+        groups);</span>
<span class='add'>+    xmpp_send(conn, iq);</span>
<span class='add'>+    xmpp_stanza_release(iq);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='del'>-roster_change_name(const char * const barejid, const char * const new_name)</span>
<span class='add'>+roster_send_add_to_group(const char * const group, PContact contact)</span>
<span class='ctx'> {</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-    const char * current_name = NULL;</span>
<span class='del'>-    if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-        current_name = strdup(p_contact_name(contact));</span>
<span class='add'>+    GSList *groups = p_contact_groups(contact);</span>
<span class='add'>+    GSList *new_groups = NULL;</span>
<span class='add'>+    while (groups != NULL) {</span>
<span class='add'>+        new_groups = g_slist_append(new_groups, strdup(groups-&gt;data));</span>
<span class='add'>+        groups = g_slist_next(groups);</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='del'>-    if (contact != NULL) {</span>
<span class='del'>-        p_contact_set_name(contact, new_name);</span>
<span class='del'>-        _replace_name(current_name, new_name, barejid);</span>
<span class='del'>-</span>
<span class='del'>-        GSList *groups = p_contact_groups(contact);</span>
<span class='del'>-</span>
<span class='del'>-        xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='del'>-        xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='del'>-        xmpp_stanza_t *iq = stanza_create_roster_set(ctx, NULL, barejid, new_name,</span>
<span class='del'>-            groups);</span>
<span class='del'>-        xmpp_send(conn, iq);</span>
<span class='del'>-        xmpp_stanza_release(iq);</span>
<span class='add'>+    new_groups = g_slist_append(new_groups, strdup(group));</span>
<span class='add'>+    // add an id handler to handle the response</span>
<span class='add'>+    char *unique_id = get_unique_id();</span>
<span class='add'>+    GroupData *data = malloc(sizeof(GroupData));</span>
<span class='add'>+    data-&gt;group = strdup(group);</span>
<span class='add'>+    if (p_contact_name(contact) != NULL) {</span>
<span class='add'>+        data-&gt;name = strdup(p_contact_name(contact));</span>
<span class='add'>+    } else {</span>
<span class='add'>+        data-&gt;name = strdup(p_contact_barejid(contact));</span>
<span class='ctx'>     }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-void</span>
<span class='del'>-roster_add_to_group(const char * const group, const char * const barejid)</span>
<span class='del'>-{</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-</span>
<span class='del'>-    if (contact != NULL) {</span>
<span class='del'>-        if (p_contact_in_group(contact, group)) {</span>
<span class='del'>-            if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-                prof_handle_already_in_group(p_contact_name(contact), group);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                prof_handle_already_in_group(p_contact_barejid(contact), group);</span>
<span class='del'>-            }</span>
<span class='del'>-            return;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        GSList *groups = p_contact_groups(contact);</span>
<span class='del'>-        GSList *new_groups = NULL;</span>
<span class='del'>-        while (groups != NULL) {</span>
<span class='del'>-            new_groups = g_slist_append(new_groups, strdup(groups-&gt;data));</span>
<span class='del'>-            groups = g_slist_next(groups);</span>
<span class='del'>-        }</span>
<span class='ctx'> </span>
<span class='del'>-        new_groups = g_slist_append(new_groups, strdup(group));</span>
<span class='del'>-</span>
<span class='del'>-        xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='del'>-        xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='del'>-</span>
<span class='del'>-        // add an id handler to handle the response</span>
<span class='del'>-        char *unique_id = get_unique_id();</span>
<span class='del'>-        GroupData *data = malloc(sizeof(GroupData));</span>
<span class='del'>-        data-&gt;group = strdup(group);</span>
<span class='del'>-        if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-            data-&gt;name = strdup(p_contact_name(contact));</span>
<span class='del'>-        } else {</span>
<span class='del'>-            data-&gt;name = strdup(p_contact_barejid(contact));</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        xmpp_id_handler_add(conn, _group_add_handler, unique_id, data);</span>
<span class='del'>-        xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, barejid,</span>
<span class='del'>-            p_contact_name(contact), new_groups);</span>
<span class='del'>-        xmpp_send(conn, iq);</span>
<span class='del'>-        xmpp_stanza_release(iq);</span>
<span class='del'>-        free(unique_id);</span>
<span class='del'>-    }</span>
<span class='add'>+    xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='add'>+    xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='add'>+    xmpp_id_handler_add(conn, _group_add_handler, unique_id, data);</span>
<span class='add'>+    xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact),</span>
<span class='add'>+        p_contact_name(contact), new_groups);</span>
<span class='add'>+    xmpp_send(conn, iq);</span>
<span class='add'>+    xmpp_stanza_release(iq);</span>
<span class='add'>+    free(unique_id);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> static int</span>
<span class='hunk'>@@ -362,50 +158,36 @@ _group_add_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> void</span>
<span class='del'>-roster_remove_from_group(const char * const group, const char * const barejid)</span>
<span class='add'>+roster_send_remove_from_group(const char * const group, PContact contact)</span>
<span class='ctx'> {</span>
<span class='del'>-    PContact contact = g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-</span>
<span class='del'>-    if (contact != NULL) {</span>
<span class='del'>-        if (!p_contact_in_group(contact, group)) {</span>
<span class='del'>-            if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-                prof_handle_not_in_group(p_contact_name(contact), group);</span>
<span class='del'>-            } else {</span>
<span class='del'>-                prof_handle_not_in_group(p_contact_barejid(contact), group);</span>
<span class='del'>-            }</span>
<span class='del'>-            return;</span>
<span class='del'>-        }</span>
<span class='del'>-</span>
<span class='del'>-        GSList *groups = p_contact_groups(contact);</span>
<span class='del'>-        GSList *new_groups = NULL;</span>
<span class='del'>-        while (groups != NULL) {</span>
<span class='del'>-            if (strcmp(groups-&gt;data, group) != 0) {</span>
<span class='del'>-                new_groups = g_slist_append(new_groups, strdup(groups-&gt;data));</span>
<span class='del'>-            }</span>
<span class='del'>-            groups = g_slist_next(groups);</span>
<span class='add'>+    GSList *groups = p_contact_groups(contact);</span>
<span class='add'>+    GSList *new_groups = NULL;</span>
<span class='add'>+    while (groups != NULL) {</span>
<span class='add'>+        if (strcmp(groups-&gt;data, group) != 0) {</span>
<span class='add'>+            new_groups = g_slist_append(new_groups, strdup(groups-&gt;data));</span>
<span class='ctx'>         }</span>
<span class='add'>+        groups = g_slist_next(groups);</span>
<span class='add'>+    }</span>
<span class='ctx'> </span>
<span class='del'>-        xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='del'>-        xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='del'>-</span>
<span class='del'>-        // add an id handler to handle the response</span>
<span class='del'>-        char *unique_id = get_unique_id();</span>
<span class='del'>-        GroupData *data = malloc(sizeof(GroupData));</span>
<span class='del'>-        data-&gt;group = strdup(group);</span>
<span class='del'>-        if (p_contact_name(contact) != NULL) {</span>
<span class='del'>-            data-&gt;name = strdup(p_contact_name(contact));</span>
<span class='del'>-        } else {</span>
<span class='del'>-            data-&gt;name = strdup(p_contact_barejid(contact));</span>
<span class='del'>-        }</span>
<span class='add'>+    xmpp_conn_t * const conn = connection_get_conn();</span>
<span class='add'>+    xmpp_ctx_t * const ctx = connection_get_ctx();</span>
<span class='ctx'> </span>
<span class='del'>-        xmpp_id_handler_add(conn, _group_remove_handler, unique_id, data);</span>
<span class='del'>-        xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, barejid,</span>
<span class='del'>-            p_contact_name(contact), new_groups);</span>
<span class='del'>-        xmpp_send(conn, iq);</span>
<span class='del'>-        xmpp_stanza_release(iq);</span>
<span class='del'>-        free(unique_id);</span>
<span class='add'>+    // add an id handler to handle the response</span>
<span class='add'>+    char *unique_id = get_unique_id();</span>
<span class='add'>+    GroupData *data = malloc(sizeof(GroupData));</span>
<span class='add'>+    data-&gt;group = strdup(group);</span>
<span class='add'>+    if (p_contact_name(contact) != NULL) {</span>
<span class='add'>+        data-&gt;name = strdup(p_contact_name(contact));</span>
<span class='add'>+    } else {</span>
<span class='add'>+        data-&gt;name = strdup(p_contact_barejid(contact));</span>
<span class='ctx'>     }</span>
<span class='ctx'> </span>
<span class='add'>+    xmpp_id_handler_add(conn, _group_remove_handler, unique_id, data);</span>
<span class='add'>+    xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact),</span>
<span class='add'>+        p_contact_name(contact), new_groups);</span>
<span class='add'>+    xmpp_send(conn, iq);</span>
<span class='add'>+    xmpp_stanza_release(iq);</span>
<span class='add'>+    free(unique_id);</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='ctx'> static int</span>
<span class='hunk'>@@ -422,107 +204,6 @@ _group_remove_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,</span>
<span class='ctx'>     return 0;</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-gboolean</span>
<span class='del'>-roster_has_pending_subscriptions(void)</span>
<span class='del'>-{</span>
<span class='del'>-    GHashTableIter iter;</span>
<span class='del'>-    gpointer key;</span>
<span class='del'>-    gpointer value;</span>
<span class='del'>-</span>
<span class='del'>-    g_hash_table_iter_init(&amp;iter, contacts);</span>
<span class='del'>-    while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='del'>-        PContact contact = (PContact) value;</span>
<span class='del'>-        if (p_contact_pending_out(contact)) {</span>
<span class='del'>-            return TRUE;</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    return FALSE;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-GSList *</span>
<span class='del'>-roster_get_contacts(void)</span>
<span class='del'>-{</span>
<span class='del'>-    GSList *result = NULL;</span>
<span class='del'>-    GHashTableIter iter;</span>
<span class='del'>-    gpointer key;</span>
<span class='del'>-    gpointer value;</span>
<span class='del'>-</span>
<span class='del'>-    g_hash_table_iter_init(&amp;iter, contacts);</span>
<span class='del'>-    while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='del'>-        result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_contacts);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // resturn all contact structs</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-GSList *</span>
<span class='del'>-roster_get_groups(void)</span>
<span class='del'>-{</span>
<span class='del'>-    return autocomplete_get_list(groups_ac);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-GSList *</span>
<span class='del'>-roster_get_group(const char * const group)</span>
<span class='del'>-{</span>
<span class='del'>-    GSList *result = NULL;</span>
<span class='del'>-    GHashTableIter iter;</span>
<span class='del'>-    gpointer key;</span>
<span class='del'>-    gpointer value;</span>
<span class='del'>-</span>
<span class='del'>-    g_hash_table_iter_init(&amp;iter, contacts);</span>
<span class='del'>-    while (g_hash_table_iter_next(&amp;iter, &amp;key, &amp;value)) {</span>
<span class='del'>-        GSList *groups = p_contact_groups(value);</span>
<span class='del'>-        while (groups != NULL) {</span>
<span class='del'>-            if (strcmp(groups-&gt;data, group) == 0) {</span>
<span class='del'>-                result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_contacts);</span>
<span class='del'>-                break;</span>
<span class='del'>-            }</span>
<span class='del'>-            groups = g_slist_next(groups);</span>
<span class='del'>-        }</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    // resturn all contact structs</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-char *</span>
<span class='del'>-roster_find_contact(char *search_str)</span>
<span class='del'>-{</span>
<span class='del'>-    return autocomplete_complete(name_ac, search_str);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-char *</span>
<span class='del'>-roster_find_jid(char *search_str)</span>
<span class='del'>-{</span>
<span class='del'>-    return autocomplete_complete(barejid_ac, search_str);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-char *</span>
<span class='del'>-roster_find_resource(char *search_str)</span>
<span class='del'>-{</span>
<span class='del'>-    return autocomplete_complete(fulljid_ac, search_str);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-char *</span>
<span class='del'>-roster_find_group(char *search_str)</span>
<span class='del'>-{</span>
<span class='del'>-    return autocomplete_complete(groups_ac, search_str);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-char *</span>
<span class='del'>-roster_barejid_from_name(const char * const name)</span>
<span class='del'>-{</span>
<span class='del'>-    return g_hash_table_lookup(name_to_barejid, name);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-PContact</span>
<span class='del'>-roster_get_contact(const char * const barejid)</span>
<span class='del'>-{</span>
<span class='del'>-    return g_hash_table_lookup(contacts, barejid);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='ctx'> static int</span>
<span class='ctx'> _roster_handle_push(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,</span>
<span class='ctx'>     void * const userdata)</span>
<span class='hunk'>@@ -556,26 +237,8 @@ _roster_handle_push(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,</span>
<span class='ctx'>         if (name == NULL) {</span>
<span class='ctx'>             name = barejid;</span>
<span class='ctx'>         }</span>
<span class='del'>-        autocomplete_remove(barejid_ac, barejid);</span>
<span class='del'>-        autocomplete_remove(name_ac, name);</span>
<span class='del'>-        g_hash_table_remove(name_to_barejid, name);</span>
<span class='del'>-</span>
<span class='del'>-        // remove each fulljid</span>
<span class='del'>-        PContact contact = roster_get_contact(barejid);</span>
<span class='del'>-        if (contact != NULL) {</span>
<span class='del'>-            GList *resources = p_contact_get_available_resources(contact);</span>
<span class='del'>-            while (resources != NULL) {</span>
<span class='del'>-                GString *fulljid = g_string_new(strdup(barejid));</span>
<span class='del'>-                g_string_append(fulljid, "/");</span>
<span class='del'>-                g_string_append(fulljid, resources-&gt;data);</span>
<span class='del'>-                autocomplete_remove(fulljid_ac, fulljid-&gt;str);</span>
<span class='del'>-                g_string_free(fulljid, TRUE);</span>
<span class='del'>-                resources = g_list_next(resources);</span>
<span class='del'>-            }</span>
<span class='del'>-        }</span>
<span class='ctx'> </span>
<span class='del'>-        // remove the contact</span>
<span class='del'>-        g_hash_table_remove(contacts, barejid);</span>
<span class='add'>+        roster_remove(name, barejid);</span>
<span class='ctx'> </span>
<span class='ctx'>         prof_handle_roster_remove(barejid);</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -642,35 +305,6 @@ _roster_handle_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,</span>
<span class='ctx'>     return 1;</span>
<span class='ctx'> }</span>
<span class='ctx'> </span>
<span class='del'>-static void</span>
<span class='del'>-_add_name_and_barejid(const char * const name, const char * const barejid)</span>
<span class='del'>-{</span>
<span class='del'>-    if (name != NULL) {</span>
<span class='del'>-        autocomplete_add(name_ac, name);</span>
<span class='del'>-        g_hash_table_insert(name_to_barejid, strdup(name), strdup(barejid));</span>
<span class='del'>-    } else {</span>
<span class='del'>-        autocomplete_add(name_ac, barejid);</span>
<span class='del'>-        g_hash_table_insert(name_to_barejid, strdup(barejid), strdup(barejid));</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static void</span>
<span class='del'>-_replace_name(const char * const current_name, const char * const new_name,</span>
<span class='del'>-    const char * const barejid)</span>
<span class='del'>-{</span>
<span class='del'>-    // current handle exists already</span>
<span class='del'>-    if (current_name != NULL) {</span>
<span class='del'>-        autocomplete_remove(name_ac, current_name);</span>
<span class='del'>-        g_hash_table_remove(name_to_barejid, current_name);</span>
<span class='del'>-        _add_name_and_barejid(new_name, barejid);</span>
<span class='del'>-    // no current handle</span>
<span class='del'>-    } else if (new_name != NULL) {</span>
<span class='del'>-        autocomplete_remove(name_ac, barejid);</span>
<span class='del'>-        g_hash_table_remove(name_to_barejid, barejid);</span>
<span class='del'>-        _add_name_and_barejid(new_name, barejid);</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='ctx'> GSList *</span>
<span class='ctx'> _get_groups_from_item(xmpp_stanza_t *item)</span>
<span class='ctx'> {</span>
<span class='hunk'>@@ -689,54 +323,3 @@ _get_groups_from_item(xmpp_stanza_t *item)</span>
<span class='ctx'> </span>
<span class='ctx'>     return groups;</span>
<span class='ctx'> }</span>
<span class='del'>-</span>
<span class='del'>-static</span>
<span class='del'>-gboolean _key_equals(void *key1, void *key2)</span>
<span class='del'>-{</span>
<span class='del'>-    gchar *str1 = (gchar *) key1;</span>
<span class='del'>-    gchar *str2 = (gchar *) key2;</span>
<span class='del'>-</span>
<span class='del'>-    return (g_strcmp0(str1, str2) == 0);</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static</span>
<span class='del'>-gint _compare_contacts(PContact a, PContact b)</span>
<span class='del'>-{</span>
<span class='del'>-    const char * utf8_str_a = NULL;</span>
<span class='del'>-    const char * utf8_str_b = NULL;</span>
<span class='del'>-</span>
<span class='del'>-    if (p_contact_name(a) != NULL) {</span>
<span class='del'>-        utf8_str_a = p_contact_name(a);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        utf8_str_a = p_contact_barejid(a);</span>
<span class='del'>-    }</span>
<span class='del'>-    if (p_contact_name(b) != NULL) {</span>
<span class='del'>-        utf8_str_b = p_contact_name(b);</span>
<span class='del'>-    } else {</span>
<span class='del'>-        utf8_str_b = p_contact_barejid(b);</span>
<span class='del'>-    }</span>
<span class='del'>-</span>
<span class='del'>-    gchar *key_a = g_utf8_collate_key(utf8_str_a, -1);</span>
<span class='del'>-    gchar *key_b = g_utf8_collate_key(utf8_str_b, -1);</span>
<span class='del'>-</span>
<span class='del'>-    gint result = g_strcmp0(key_a, key_b);</span>
<span class='del'>-</span>
<span class='del'>-    g_free(key_a);</span>
<span class='del'>-    g_free(key_b);</span>
<span class='del'>-</span>
<span class='del'>-    return result;</span>
<span class='del'>-}</span>
<span class='del'>-</span>
<span class='del'>-static gboolean</span>
<span class='del'>-_datetimes_equal(GDateTime *dt1, GDateTime *dt2)</span>
<span class='del'>-{</span>
<span class='del'>-    if ((dt1 == NULL) &amp;&amp; (dt2 == NULL)) {</span>
<span class='del'>-        return TRUE;</span>
<span class='del'>-    } else if ((dt1 == NULL) &amp;&amp; (dt2 != NULL)) {</span>
<span class='del'>-        return FALSE;</span>
<span class='del'>-    } else if ((dt1 != NULL) &amp;&amp; (dt2 == NULL)) {</span>
<span class='del'>-        return FALSE;</span>
<span class='del'>-    } else {</span>
<span class='del'>-        return g_date_time_equal(dt1, dt2);</span>
<span class='del'>-    }</span>
<span class='del'>-}</span>
<span class='head'>diff --git a/src/xmpp/roster.h b/src/xmpp/roster.h
index 8aba28f4..1faaba86 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/roster.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/roster.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/roster.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/roster.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef ROSTER_H</span>
<span class='del'>-#define ROSTER_H</span>
<span class='add'>+#ifndef XMPP_ROSTER_H</span>
<span class='add'>+#define XMPP_ROSTER_H</span>
<span class='ctx'> </span>
<span class='ctx'> void roster_add_handlers(void);</span>
<span class='ctx'> void roster_request(void);</span>
<span class='head'>diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 108b0806..6b647258 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/stanza.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/stanza.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/stanza.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/stanza.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef STANZA_H</span>
<span class='del'>-#define STANZA_H</span>
<span class='add'>+#ifndef XMPP_STANZA_H</span>
<span class='add'>+#define XMPP_STANZA_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include &lt;strophe.h&gt;</span>
<span class='ctx'> </span>
<span class='head'>diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index f1b3ba6c..21c25aa4 100644
--- a/<a href='/danisanti/profani-tty/tree/src/xmpp/xmpp.h?id=06367723d7b97abe1958944b651cdbbf9b5c856a'>src/xmpp/xmpp.h</a>
+++ b/<a href='/danisanti/profani-tty/tree/src/xmpp/xmpp.h?id=2470f642c73a7b13181bf51a6f3c2ee126e9e733'>src/xmpp/xmpp.h</a>
</span><span class='hunk'>@@ -20,8 +20,8 @@</span>
<span class='ctx'>  *</span>
<span class='ctx'>  */</span>
<span class='ctx'> </span>
<span class='del'>-#ifndef XMPP_H</span>
<span class='del'>-#define XMPP_H</span>
<span class='add'>+#ifndef XMPP_XMPP_H</span>
<span class='add'>+#define XMPP_XMPP_H</span>
<span class='ctx'> </span>
<span class='ctx'> #include &lt;strophe.h&gt;</span>
<span class='ctx'> </span>
<span class='hunk'>@@ -124,32 +124,16 @@ void iq_disco_items_request(gchar *jid);</span>
<span class='ctx'> Capabilities* caps_get(const char * const caps_str);</span>
<span class='ctx'> void caps_close(void);</span>
<span class='ctx'> </span>
<span class='del'>-void roster_clear(void);</span>
<span class='del'>-gboolean roster_update_presence(const char * const barejid,</span>
<span class='del'>-    Resource *resource, GDateTime *last_activity);</span>
<span class='del'>-PContact roster_get_contact(const char * const barejid);</span>
<span class='del'>-gboolean roster_contact_offline(const char * const barejid,</span>
<span class='del'>-    const char * const resource, const char * const status);</span>
<span class='del'>-void roster_reset_search_attempts(void);</span>
<span class='del'>-void roster_init(void);</span>
<span class='del'>-void roster_free(void);</span>
<span class='del'>-gboolean roster_has_pending_subscriptions(void);</span>
<span class='del'>-GSList * roster_get_contacts(void);</span>
<span class='del'>-char * roster_find_contact(char *search_str);</span>
<span class='del'>-char * roster_find_jid(char *search_str);</span>
<span class='del'>-char * roster_find_resource(char *search_str);</span>
<span class='del'>-char * roster_find_group(char *search_str);</span>
<span class='del'>-gboolean roster_add(const char * const barejid, const char * const name,</span>
<span class='del'>-    GSList *groups, const char * const subscription, gboolean pending_out,</span>
<span class='del'>-    gboolean from_initial);</span>
<span class='del'>-void roster_change_name(const char * const barejid, const char * const new_name);</span>
<span class='del'>-char * roster_barejid_from_name(const char * const name);</span>
<span class='add'>+void bookmark_add(const char *jid, const char *nick, gboolean autojoin);</span>
<span class='add'>+void bookmark_remove(const char *jid, gboolean autojoin);</span>
<span class='add'>+const GList *bookmark_get_list(void);</span>
<span class='add'>+char *bookmark_find(char *search_str);</span>
<span class='add'>+void bookmark_autocomplete_reset(void);</span>
<span class='add'>+</span>
<span class='add'>+void roster_send_name_change(const char * const barejid, const char * const new_name, GSList *groups);</span>
<span class='add'>+void roster_send_add_to_group(const char * const group, PContact contact);</span>
<span class='add'>+void roster_send_remove_from_group(const char * const group, PContact contact);</span>
<span class='ctx'> void roster_add_new(const char * const barejid, const char * const name);</span>
<span class='del'>-void roster_remove(const char * const barejid);</span>
<span class='del'>-GSList * roster_get_group(const char * const group);</span>
<span class='del'>-void roster_add_to_group(const char * const group, const char * const barejid);</span>
<span class='del'>-void roster_remove_from_group(const char * const group,</span>
<span class='del'>-    const char * const barejid);</span>
<span class='del'>-GSList * roster_get_groups(void);</span>
<span class='add'>+void roster_send_remove(const char * const barejid);</span>
<span class='ctx'> </span>
<span class='ctx'> #endif</span>
</pre></td></tr></table></div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.causal.agency/cgit-pink/about/'>cgit-pink 1.4.1-2-gfad0</a> (<a href='https://git-scm.com/'>git 2.36.2.497.gbbea4dcf42</a>) at 2025-05-31 02:48:09 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
