Changeset 6e9ae72


Ignore:
Timestamp:
2011-12-17T13:50:01Z (7 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
18c6d36
Parents:
87dddee (diff), 17f057d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Mainline merge.

Files:
25 added
51 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r87dddee r6e9ae72  
    2727subdirobjs = $(foreach dir,$(subdirs),$(dir)/$(dir).o)
    2828
    29 all: $(OUTFILE) $(OTR_PI) systemd
     29all: $(OUTFILE) $(OTR_PI) $(SKYPE_PI) systemd
    3030        $(MAKE) -C doc
     31ifdef SKYPE_PI
     32        $(MAKE) -C protocols/skype doc
     33endif
    3134
    3235uninstall: uninstall-bin uninstall-doc
     
    7174install-doc:
    7275        $(MAKE) -C doc install
     76ifdef SKYPE_PI
     77        $(MAKE) -C protocols/skype install-doc
     78endif
    7379
    7480uninstall-doc:
    7581        $(MAKE) -C doc uninstall
     82ifdef SKYPE_PI
     83        $(MAKE) -C protocols/skype uninstall-doc
     84endif
    7685
    7786install-bin:
    78         mkdir -p $(DESTDIR)$(BINDIR)
    79         install -m 0755 $(OUTFILE) $(DESTDIR)$(BINDIR)/$(OUTFILE)
     87        mkdir -p $(DESTDIR)$(SBINDIR)
     88        install -m 0755 $(OUTFILE) $(DESTDIR)$(SBINDIR)/$(OUTFILE)
    8089
    8190uninstall-bin:
    82         rm -f $(DESTDIR)$(BINDIR)/$(OUTFILE)
     91        rm -f $(DESTDIR)$(SBINDIR)/$(OUTFILE)
    8392
    8493install-dev:
     
    104113        -rmdir $(DESTDIR)$(ETCDIR)
    105114
    106 install-plugins:
     115install-plugins: install-plugin-otr install-plugin-skype
     116
     117install-plugin-otr:
    107118ifdef OTR_PI
    108119        mkdir -p $(DESTDIR)$(PLUGINDIR)
    109120        install -m 0755 otr.so $(DESTDIR)$(PLUGINDIR)
     121endif
     122
     123install-plugin-skype:
     124ifdef SKYPE_PI
     125        mkdir -p $(DESTDIR)$(PLUGINDIR)
     126        install -m 0755 skype.so $(DESTDIR)$(PLUGINDIR)
     127        mkdir -p $(DESTDIR)$(ETCDIR)/../skyped $(DESTDIR)$(BINDIR)
     128        install -m 0644 $(SRCDIR)protocols/skype/skyped.cnf $(DESTDIR)$(ETCDIR)/../skyped/skyped.cnf
     129        install -m 0644 $(SRCDIR)protocols/skype/skyped.conf.dist $(DESTDIR)$(ETCDIR)/../skyped/skyped.conf
     130        install -m 0755 $(SRCDIR)protocols/skype/skyped.py $(DESTDIR)$(BINDIR)/skyped
     131        make -C protocols/skype install-doc
    110132endif
    111133
     
    139161$(OTR_PI): %.so: $(SRCDIR)%.c
    140162        @echo '*' Building plugin $@
    141         @$(CC) $(CFLAGS) $(OTRFLAGS) -fPIC -shared $(LDFLAGS) $< -o $@
     163        @$(CC) $(CFLAGS) -fPIC -shared $(LDFLAGS) $< -o $@ $(OTRFLAGS)
     164
     165$(SKYPE_PI): $(SRCDIR)protocols/skype/skype.c
     166        @echo '*' Building plugin skype
     167        @$(CC) $(CFLAGS) -fPIC -shared $< -o $@
    142168
    143169$(objects): %.o: $(SRCDIR)%.c
     
    164190
    165191-include .depend/*.d
     192# DO NOT DELETE
  • bitlbee.h

    r87dddee r6e9ae72  
    3535
    3636#define PACKAGE "BitlBee"
    37 #define BITLBEE_VERSION "3.0.3"
     37#define BITLBEE_VERSION "3.0.4"
    3838#define VERSION BITLBEE_VERSION
    3939#define BITLBEE_VER(a,b,c) (((a) << 16) + ((b) << 8) + (c))
    40 #define BITLBEE_VERSION_CODE BITLBEE_VER(3, 0, 3)
     40#define BITLBEE_VERSION_CODE BITLBEE_VER(3, 0, 4)
    4141
    4242#define MAX_STRING 511
  • configure

    r87dddee r6e9ae72  
    99
    1010prefix='/usr/local/'
    11 bindir='$prefix/sbin/'
     11bindir='$prefix/bin/'
     12sbindir='$prefix/sbin/'
    1213etcdir='$prefix/etc/bitlbee/'
    1314mandir='$prefix/share/man/'
     
    1920libevent='/usr/'
    2021pidfile='/var/run/bitlbee.pid'
    21 ipcsocket='/var/run/bitlbee.sock'
     22ipcsocket=''
    2223pcdir='$prefix/lib/pkgconfig'
    2324systemlibdirs="/lib /lib64 /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64"
     
    2829yahoo=1
    2930twitter=1
    30 twitter=1
    3131purple=0
    3232
     
    3636plugins=1
    3737otr=0
     38skype=0
    3839
    3940events=glib
     
    5960--prefix=...    Directories to put files in             $prefix
    6061--bindir=...                                            $bindir
     62--sbindir=...                                           $sbindir
    6163--etcdir=...                                            $etcdir
    6264--mandir=...                                            $mandir
     
    6668--pidfile=...                                           $pidfile
    6769--config=...                                            $config
    68 --ipcsocket=...                                         $ipcsocket
    6970
    7071--msn=0/1       Disable/enable MSN part                 $msn
     
    8384--otr=0/1/auto/plugin
    8485                Disable/enable OTR encryption support   $otr
     86--skype=0/1/plugin
     87                Disable/enable Skype support            $skype
    8588
    8689--events=...    Event handler (glib, libevent)          $events
     
    98101# Expand $prefix and get rid of double slashes
    99102bindir=`eval echo "$bindir/" | sed 's/\/\{1,\}/\//g'`
     103sbindir=`eval echo "$sbindir/" | sed 's/\/\{1,\}/\//g'`
    100104etcdir=`eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g'`
    101105mandir=`eval echo "$mandir/" | sed 's/\/\{1,\}/\//g'`
     
    110114pcdir=`eval echo "$pcdir" | sed 's/\/\{1,\}/\//g'`
    111115
     116protocols_mods=""
     117
    112118cat<<EOF>Makefile.settings
    113119## BitlBee settings, generated by configure
    114120PREFIX=$prefix
    115121BINDIR=$bindir
     122SBINDIR=$sbindir
    116123ETCDIR=$etcdir
    117124MANDIR=$mandir
     
    323330
    324331RESOLV_TESTCODE='
     332#include <sys/types.h>
     333#include <netinet/in.h>
    325334#include <arpa/nameser.h>
    326335#include <resolv.h>
     
    335344detect_resolv_dynamic()
    336345{
     346        case "$arch" in
     347        FreeBSD )
     348                # In FreeBSD res_* routines are present in libc.so
     349                LIBRESOLV=;;
     350        * )
     351                LIBRESOLV=-lresolv;;
     352        esac
    337353        TMPFILE=$(mktemp /tmp/bitlbee-configure.XXXXXX)
    338354        ret=1
    339         echo "$RESOLV_TESTCODE" | $CC -o $TMPFILE -x c - -lresolv >/dev/null 2>/dev/null
     355        echo "$RESOLV_TESTCODE" | $CC -o $TMPFILE -x c - $LIBRESOLV >/dev/null 2>/dev/null
    340356        if [ "$?" = "0" ]; then
    341                 echo 'EFLAGS+=-lresolv' >> Makefile.settings
     357                echo "EFLAGS+=$LIBRESOLV" >> Makefile.settings
    342358                ret=0
    343359        fi
     
    538554fi
    539555
     556if [ "$skype" = "1" -o "$skype" = "plugin" ]; then
     557        echo 'SKYPE_PI=skype.so' >> Makefile.settings
     558        protocols_mods="$protocol_mods skype(plugin)"
     559fi
     560
    540561if [ ! -e doc/user-guide/help.txt ] && ! type xmlto > /dev/null 2> /dev/null; then
    541562        echo
     
    751772
    752773if [ -n "$protocols" ]; then
    753         echo '  Building with these protocols:' $protocols
     774        echo '  Building with these protocols:' $protocols$protocols_mods
    754775        case "$protocols" in
    755776        *purple*)
  • debian/changelog

    r87dddee r6e9ae72  
     1bitlbee (3.0.4-1) unstable; urgency=low
     2
     3  * New upstream release.
     4  * Added bitlbee-plugin-skype and skyped packages, now part of BitlBee
     5    instead of a separate package.
     6  * Fixed dependencies of bitlbee-plugin-otr package to not break with
     7    binary MTUs. (Closes: #651612)
     8  * ^B and some other things are stripped in outgoing XMPP stanzas.
     9    (Closes: #507856)
     10  * OTR module linking fix. Not with the fix from the Debian bug but with
     11    one from bugs.bitlbee.org. I hope that covers it. (Closes: #646369)
     12  * Closing a few old bugs that were filed against the Debian package
     13    instead of upstream:
     14    - Joining password-protected MUCs is working for a while already, set
     15      the password using "chan set". (Closes: #615624)
     16    - "Headline:" msgs (Closes: #605459)
     17    - Yahoo! was fixed long ago and Etch is deprecated. (Closes: #476529)
     18    - identi.ca support is documented. (Closes: #613789)
     19
     20 -- Wilmer van der Gaast <wilmer@gaast.net>  Sun, 11 Dec 2011 16:53:31 +0000
     21
    122bitlbee (3.0.3-1) unstable; urgency=low
    223
  • debian/control

    r87dddee r6e9ae72  
    55Uploaders: Jelmer Vernooij <jelmer@samba.org>
    66Standards-Version: 3.9.1
    7 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), po-debconf, libpurple-dev, libotr2-dev, debhelper (>= 6.0.7~)
     7Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), po-debconf, libpurple-dev, libotr2-dev, debhelper (>= 6.0.7~), asciidoc
    88Homepage: http://www.bitlbee.org/
    99Vcs-Bzr: http://code.bitlbee.org/bitlbee/
     
    6161Package: bitlbee-plugin-otr
    6262Architecture: any
    63 Depends: ${misc:Depends}, ${shlibs:Depends}, bitlbee (= ${bee:Version}) | bitlbee-libpurple (= ${bee:Version}), bitlbee-common (= ${bee:Version})
     63Depends: ${misc:Depends}, ${shlibs:Depends}, bitlbee (>= ${bee:Version}) | bitlbee-libpurple (>= ${bee:Version}), bitlbee (<< ${bee:Version}.1~) | bitlbee-libpurple (<< ${bee:Version}.1~), bitlbee-common (= ${bee:Version})
    6464Description: An IRC to other chat networks gateway (OTR plugin)
    6565 This program can be used as an IRC server which forwards everything you
     
    6969 This package contains a plugin that adds support for Off-The-Record
    7070 encryption of instant messages.
     71
     72Package: bitlbee-plugin-skype
     73Architecture: any
     74Depends: ${shlibs:Depends}, ${misc:Depends}, bitlbee (>= ${bee:Version}) | bitlbee-libpurple (>= ${bee:Version}), bitlbee (<< ${bee:Version}.1~) | bitlbee-libpurple (<< ${bee:Version}.1~)
     75Recommends: skyped
     76Description: An IRC to other chat networks gateway (Skype plugin)
     77 This program can be used as an IRC server which forwards everything you
     78 say to people on other chat networks: Jabber (which includes Google Talk
     79 and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net.
     80 .
     81 This package contains a plugin that adds support for the Skype IM network.
     82 You need to download and install the Skype client for this to work.
     83
     84Package: skyped
     85Architecture: any
     86Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.5), python-gnutls, python-skype (>=0.9.28.7)
     87Recommends: skype
     88Description: Daemon to control Skype remotely
     89 Daemon to control the GUI Skype client. Currently required to control Skype
     90 from the BitlBee IRC2IM gateway. Skyped and Skype can run on a different
     91 host than the BitlBee server, the communication is encrypted.
     92 .
     93 You need to download and install the Skype client for this to work.
  • debian/rules

    r87dddee r6e9ae72  
    1111BITLBEE_LIBPURPLE ?= 1
    1212BITLBEE_OTR ?= plugin
     13BITLBEE_SKYPE ?= plugin
    1314BITLBEE_CONFIGURE_FLAGS ?=
    1415DEBUG ?= 0
     
    2728endif
    2829
     30ifneq ($(BITLBEE_SKYPE),plugin)
     31DH_OPTIONS += -Nbitlbee-plugin-skype -Nskyped
     32endif
     33
    2934build: build-stamp
    3035build-stamp:
     
    3237
    3338        mkdir -p debian/build-native
    34         ROOT=$$PWD; cd debian/build-native; $(BITLBEE_CONFIGURE_VERSION) $$ROOT/configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent --otr=$(BITLBEE_OTR) $(BITLBEE_CONFIGURE_FLAGS)
     39        ROOT=$$PWD; cd debian/build-native; $(BITLBEE_CONFIGURE_VERSION) $$ROOT/configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent --otr=$(BITLBEE_OTR) --skype=$(BITLBEE_SKYPE) $(BITLBEE_CONFIGURE_FLAGS)
    3540        $(MAKE) -C debian/build-native
    3641
     
    6469        $(MAKE) -C debian/build-native install-etc install-doc DESTDIR=`pwd`/debian/bitlbee-common
    6570        $(MAKE) -C debian/build-native install-dev DESTDIR=`pwd`/debian/bitlbee-dev
    66         $(MAKE) -C debian/build-native install-plugins DESTDIR=`pwd`/debian/bitlbee-plugin-otr
     71        $(MAKE) -C debian/build-native install-plugin-otr DESTDIR=`pwd`/debian/bitlbee-plugin-otr
     72        $(MAKE) -C debian/build-native install-plugin-skype DESTDIR=`pwd`/debian/skyped
     73
     74        mkdir -p debian/bitlbee-plugin-skype/usr
     75        mv debian/skyped/usr/lib debian/bitlbee-plugin-skype/usr
     76
     77        mkdir -p debian/skyped/usr/share/man/man1
     78        mv debian/bitlbee-common/usr/share/man/man1/skyped* debian/skyped/usr/share/man/man1
    6779
    6880ifeq ($(BITLBEE_LIBPURPLE),1)
  • doc/CHANGES

    r87dddee r6e9ae72  
    33
    44http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
     5
     6Version 3.0.4:
     7- Merged Skype support. This used to be a separate plugin, and it still is,
     8  but by including it with BitlBee by default it will be easier to keep it
     9  in sync with changes to BitlBee.
     10- Fixed a file descriptor leak bug that may have caused strange behaviour
     11  in BitlBee sessions running for a long time.
     12- Now fetches Twitter mentions as well if the "fetch_mentions" account
     13  setting is enabled.
     14- With t.co now all over Twitter, show the original (but truncated) URL
     15  between <brackets>.
     16- Fixed MSN Messenger login issues ("timeout" while fetching buddy list).
     17- Another (related) GnuTLS compatibility fix (now 2.13+?).
     18
     19Finished 4 Dec 2011 (Exactly 6 years since 1.0!)
    520
    621Version 3.0.3:
  • doc/user-guide/commands.xml

    r87dddee r6e9ae72  
    852852
    853853                        <variablelist>
    854                                 <varlistentry><term>undo [&lt;id&gt;]</term><listitem><para>Delete your last Tweet (or one with the given ID)</para></listitem></varlistentry>
    855                                 <varlistentry><term>rt &lt;screenname|id&gt;</term><listitem><para>Retweet someone's last Tweet (or one with the given ID)</para></listitem></varlistentry>
    856                                 <varlistentry><term>reply &lt;screenname|id&gt;</term><listitem><para>Reply to a Tweet (with a reply-to reference)</para></listitem></varlistentry>
     854                                <varlistentry><term>undo #[&lt;id&gt;]</term><listitem><para>Delete your last Tweet (or one with the given ID)</para></listitem></varlistentry>
     855                                <varlistentry><term>rt &lt;screenname|#id&gt;</term><listitem><para>Retweet someone's last Tweet (or one with the given ID)</para></listitem></varlistentry>
     856                                <varlistentry><term>reply &lt;screenname|#id&gt;</term><listitem><para>Reply to a Tweet (with a reply-to reference)</para></listitem></varlistentry>
    857857                                <varlistentry><term>follow &lt;screenname&gt;</term><listitem><para>Start following a person</para></listitem></varlistentry>
    858858                                <varlistentry><term>unfollow &lt;screenname&gt;</term><listitem><para>Stop following a person</para></listitem></varlistentry>
  • doc/user-guide/help.xsl

    r87dddee r6e9ae72  
    7373
    7474        <xsl:template match="command-list">
     75                <xsl:text>These are all root commands. See _b_help &lt;command name&gt;_b_ for more details on each command.&#10;&#10;</xsl:text>
    7576                <xsl:for-each select="../bitlbee-command">
    7677                        <xsl:text> * _b_</xsl:text><xsl:value-of select="@name"/><xsl:text>_b_ - </xsl:text><xsl:value-of select="short-description"/><xsl:text>&#10;</xsl:text>
    7778                </xsl:for-each>
     79                <xsl:text>&#10;Most commands can be shortened. For example instead of _b_account list_b_, try _b_ac l_b_.&#10;</xsl:text>
    7880                <xsl:text>&#10;</xsl:text>
    7981        </xsl:template>
  • doc/user-guide/misc.xml

    r87dddee r6e9ae72  
    191191
    192192<ircexample>
    193         <ircline nick="wilmer">chan set &amp;wlm fill_by account</ircline>
     193        <ircline nick="wilmer">chan &amp;wlm set fill_by account</ircline>
    194194        <ircline nick="root">fill_by = `account'</ircline>
    195         <ircline nick="wilmer">chan set &amp;wlm account msn</ircline>
     195        <ircline nick="wilmer">chan &amp;wlm set account msn</ircline>
    196196        <ircline nick="root">account = `msn'</ircline>
    197197</ircexample>
     
    204204
    205205<ircexample>
    206         <ircline nick="wilmer">chan set &amp;offline show_users offline</ircline>
     206        <ircline nick="wilmer">chan &amp;offline set show_users offline</ircline>
    207207        <ircline nick="root">show_users = `offline'</ircline>
    208208</ircexample>
  • doc/user-guide/quickstart.xml

    r87dddee r6e9ae72  
    5353
    5454<sect1 id="quickstart3">
    55 <title>Managing Contact Lists: Rename</title>
    56 
    57 <!--quickstart3-->
    58 <para>
    59 <emphasis>Step Three: Managing Contact Lists: Rename</emphasis>
    60 </para>
    61 
    62 <para>
    63 Now BitlBee logs in and downloads the contact list from the IM server. In a few seconds, all your on-line buddies should show up in the control channel.
    64 </para>
    65 
    66 <para>
    67 BitlBee will convert names into IRC-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo.
    68 </para>
    69 
    70 <para>
    71 It would be easy to get these two mixed up, so BitlBee has a <emphasis>rename</emphasis> command to change the nickname into something more suitable: <emphasis>rename &lt;oldnick&gt; &lt;newnick&gt;</emphasis>
    72 </para>
    73 
    74 <ircexample>
    75         <ircline nick="you">rename tux_ bitlbeetux</ircline>
    76         <ircaction nick="tux_">is now known as <emphasis>bitlbeetux</emphasis></ircaction>
    77         <ircline nick="root">Nick successfully changed</ircline>
    78 </ircexample>
    79 
    80 <para>
    81 When finished, type <emphasis>help quickstart4</emphasis> to continue.
    82 </para>
    83 
    84 </sect1>
    85 
    86 <sect1 id="quickstart4">
    87 <title>Step Four: Managing Contact Lists: Add and Remove.</title>
    88 
    89 <para>
    90 <emphasis>Step Four: Managing Contact Lists: Add and Remove.</emphasis>
    91 </para>
     55<title>Step Four: Managing Contact Lists: Add, Remove and Rename</title>
    9256
    9357<para>
     
    10569
    10670<para>
    107 Lets say you accidentally added r2d3@example.com rather than r2d2@example.com, or maybe you just want to remove a user from your list because you never talk to them. To remove a name you will want to use the <emphasis>remove</emphasis> command: <emphasis>remove &lt;nick&gt;</emphasis>
     71Lets say you accidentally added r2d3@example.com rather than r2d2@example.com, or maybe you just want to remove a user from your list because you never talk to them. To remove a name you will want to use the <emphasis>remove</emphasis> command: <emphasis>remove r2d3</emphasis>
    10872</para>
    10973
    11074<para>
    111 When finished, type <emphasis>help quickstart5</emphasis> to continue.
     75Finally, if you have multiple users with similar names you may use the <emphasis>rename</emphasis> command to make it easier to remember: <emphasis>rename r2d2_ r2d2_aim</emphasis>
     76</para>
     77
     78<para>
     79When finished, type <emphasis>help quickstart4</emphasis> to continue.
    11280</para>
    11381
    11482</sect1>
    11583
    116 <sect1 id="quickstart5">
     84<sect1 id="quickstart4">
    11785<title>Chatting</title>
    11886
     
    139107
    140108<para>
    141 You know the basics. If you want to get to know more about BitlBee, please type <emphasis>help quickstart6</emphasis>.
     109You know the basics. If you want to know about some of the neat features BitlBee offers, please type <emphasis>help quickstart5</emphasis>.
    142110</para>
    143111
    144112</sect1>
    145113
    146 <sect1 id="quickstart6">
     114<sect1 id="quickstart5">
    147115<title>Further Resources</title>
    148116
    149117<para>
    150 <emphasis>So you want more than just chatting? Or maybe you're just looking for a feature?</emphasis>
     118<emphasis>So you want more than just chatting? Or maybe you're just looking for more features?</emphasis>
     119</para>
     120
     121<para>
     122With multiple channel support you can have contacts for specific protocols in their own channels, for instance, if you <emphasis>/join &amp;msn</emphasis> you will join a channel that only contains your MSN contacts.
     123</para>
     124
     125<para>
     126Account tagging allows you to use the given account name rather than a number when referencing your account. If you wish to turn off your gtalk account, you may <emphasis>account gtalk off</emphasis> rather than <emphasis>account 3 off</emphasis> where "3" is the account number.
    151127</para>
    152128
  • ipc.c

    r87dddee r6e9ae72  
    356356                        irc_switch_fd( irc, ipc_child_recv_fd );
    357357                        irc_sync( irc );
    358                         irc_usermsg( irc, "You've successfully taken over your old session" );
     358                        irc_rootmsg( irc, "You've successfully taken over your old session" );
    359359                        ipc_child_recv_fd = -1;
    360360                       
     
    374374        {
    375375                /* Master->New connection */
    376                 irc_usermsg( irc, "Could not take over old session" );
     376                irc_rootmsg( irc, "Could not take over old session" );
    377377        }
    378378}
     
    412412        /* Drop credentials, we'll shut down soon and shouldn't overwrite
    413413           any settings. */
    414         irc_usermsg( irc, "Trying to take over existing session" );
     414        irc_rootmsg( irc, "Trying to take over existing session" );
    415415       
    416416        irc_desync( irc );
     
    909909        int serversock;
    910910
     911        if (!IPCSOCKET || !*IPCSOCKET)
     912                return 1;
     913
    911914        /* Clean up old socket files that were hanging around.. */
    912915        if (unlink(IPCSOCKET) == -1 && errno != ENOENT) {
  • irc.c

    r87dddee r6e9ae72  
    363363                                        if( irc->status & USTATUS_LOGGED_IN )
    364364                                        {
    365                                                 irc_usermsg( irc, "Error: Charset mismatch detected. The charset "
     365                                                irc_rootmsg( irc, "Error: Charset mismatch detected. The charset "
    366366                                                                  "setting is currently set to %s, so please make "
    367367                                                                  "sure your IRC client will send and accept text in "
     
    767767                        irc->root->last_channel = irc->default_channel;
    768768                       
    769                         irc_usermsg( irc,
     769                        irc_rootmsg( irc,
    770770                                     "Welcome to the BitlBee gateway!\n\n"
    771771                                     "If you've never used BitlBee before, please do read the help "
     
    910910                g_free( test );
    911911                g_iconv_close( oc );
    912                 irc_usermsg( irc, "Unsupported character set: The IRC protocol "
     912                irc_rootmsg( irc, "Unsupported character set: The IRC protocol "
    913913                                  "only supports 8-bit character sets." );
    914914                return NULL;
     
    941941        GSList *l;
    942942       
    943         irc_usermsg( irc, "Setting `%s' is obsolete, use the `show_users' "
     943        irc_rootmsg( irc, "Setting `%s' is obsolete, use the `show_users' "
    944944                     "channel setting instead.", set->key );
    945945       
  • irc.h

    r87dddee r6e9ae72  
    317317void irc_send_login( irc_t *irc );
    318318void irc_send_motd( irc_t *irc );
    319 void irc_usermsg( irc_t *irc, char *format, ... );
     319const char *irc_user_msgdest( irc_user_t *iu );
     320void irc_rootmsg( irc_t *irc, char *format, ... );
     321void irc_usermsg( irc_user_t *iu, char *format, ... );
     322void irc_usernotice( irc_user_t *iu, char *format, ... );
    320323void irc_send_join( irc_channel_t *ic, irc_user_t *iu );
    321324void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason );
  • irc_commands.c

    r87dddee r6e9ae72  
    9292                        irc->status &= ~USTATUS_IDENTIFIED;
    9393                        irc_umode_set( irc, "-R", 1 );
    94                         irc_usermsg( irc, "Changing nicks resets your identify status. "
     94                        irc_rootmsg( irc, "Changing nicks resets your identify status. "
    9595                                     "Re-identify or register a new account if you want "
    9696                                     "your configuration to be saved. See \x02help "
     
    433433                        {
    434434                                set_setstr( &a->set, "password", password );
    435                                 irc_usermsg( irc, "Password added to IM account "
    436                                              "%s(%s)", a->prpl->name, a->user );
     435                                irc_rootmsg( irc, "Password added to IM account "
     436                                             "%s", a->tag );
    437437                                /* The IRC client may expect this. 491 suggests the OPER
    438438                                   password was wrong, so the client won't expect a +o.
    439439                                   It may however repeat the password prompt. We'll see. */
    440440                                irc_send_num( irc, 491, ":Password added to IM account "
    441                                               "%s(%s)", a->prpl->name, a->user );
     441                                              "%s", a->tag );
    442442                        }
    443443        }
  • irc_im.c

    r87dddee r6e9ae72  
    197197        irc_t *irc = bee->ui_data;
    198198        irc_user_t *iu = (irc_user_t *) bu->ui_data;
    199         char *dst, *prefix = NULL;
     199        const char *dst;
     200        char *prefix = NULL;
    200201        char *wrapped, *ts = NULL;
    201         irc_channel_t *ic = NULL;
    202202        char *msg = g_strdup( msg_ );
    203203        GSList *l;
     
    206206                ts = irc_format_timestamp( irc, sent_at );
    207207       
    208         /* Too similar to irc_usermsg()... */
    209         if( iu->last_channel )
    210         {
    211                 if( iu->last_channel->flags & IRC_CHANNEL_JOINED )
    212                         ic = iu->last_channel;
    213                 else
    214                         ic = irc_channel_with_user( irc, iu );
    215         }
    216        
    217         if( ic )
    218         {
    219                 dst = ic->name;
     208        dst = irc_user_msgdest( iu );
     209        if( dst != irc->user->nick )
     210        {
     211                /* if not messaging directly, call user by name */
    220212                prefix = g_strdup_printf( "%s%s%s", irc->user->nick, set_getstr( &bee->set, "to_char" ), ts ? : "" );
    221213        }
    222214        else
    223215        {
    224                 dst = irc->user->nick;
    225216                prefix = ts;
    226                 ts = NULL;
     217                ts = NULL;      /* don't double-free */
    227218        }
    228219       
     
    995986        else if( !acc->prpl->chat_join )
    996987        {
    997                 irc_usermsg( ic->irc, "Named chatrooms not supported on that account." );
     988                irc_rootmsg( ic->irc, "Named chatrooms not supported on that account." );
    998989                return SET_INVALID;
    999990        }
  • irc_send.c

    r87dddee r6e9ae72  
    110110}
    111111
    112 void irc_usermsg( irc_t *irc, char *format, ... )
    113 {
     112/* Used by some funcs that generate PRIVMSGs to figure out if we're talking to
     113   this person in /query or in a control channel. WARNING: callers rely on
     114   this returning a pointer at irc->user_nick, not a copy of it. */
     115const char *irc_user_msgdest( irc_user_t *iu )
     116{
     117        irc_t *irc = iu->irc;
    114118        irc_channel_t *ic = NULL;
    115         irc_user_t *iu = irc->root;
    116         char text[2048];
    117         va_list params;
    118         char *dst;
    119        
    120         va_start( params, format );
    121         g_vsnprintf( text, sizeof( text ), format, params );
    122         va_end( params );
    123        
    124         /* Too similar to bee_irc_user_msg()... */
     119
    125120        if( iu->last_channel )
    126121        {
     
    128123                        ic = iu->last_channel;
    129124                else
    130                         ic = irc_channel_with_user( irc, irc->root );
     125                        ic = irc_channel_with_user( irc, iu );
    131126        }
    132127       
    133128        if( ic )
    134                 dst = ic->name;
     129                return ic->name;
    135130        else
    136                 dst = irc->user->nick;
    137        
    138         irc_send_msg( irc->root, "PRIVMSG", dst, text, NULL );
     131                return irc->user->nick;
     132}
     133
     134/* cmd = "PRIVMSG" or "NOTICE" */
     135static void irc_usermsg_( const char *cmd, irc_user_t *iu, const char *format, va_list params )
     136{
     137        char text[2048];
     138        const char *dst;
     139       
     140        g_vsnprintf( text, sizeof( text ), format, params );
     141       
     142        dst = irc_user_msgdest( iu );
     143        irc_send_msg( iu, cmd, dst, text, NULL );
     144}
     145
     146void irc_usermsg(irc_user_t *iu, char *format, ... )
     147{
     148        va_list params;
     149        va_start( params, format );
     150        irc_usermsg_( "PRIVMSG", iu, format, params );
     151        va_end( params );
     152}
     153
     154void irc_usernotice(irc_user_t *iu, char *format, ... )
     155{
     156        va_list params;
     157        va_start( params, format );
     158        irc_usermsg_( "NOTICE", iu, format, params );
     159        va_end( params );
     160}
     161
     162void irc_rootmsg( irc_t *irc, char *format, ... )
     163{
     164        va_list params;
     165        va_start( params, format );
     166        irc_usermsg_( "PRIVMSG", irc->root, format, params );
     167        va_end( params );
    139168}
    140169
  • lib/http_client.c

    r87dddee r6e9ae72  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2005 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2011 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    6969        req->request_length = strlen( request );
    7070        req->redir_ttl = 3;
     71       
     72        if( getenv( "BITLBEE_DEBUG" ) )
     73                printf( "About to send HTTP request:\n%s\n", req->request );
    7174       
    7275        return( req );
     
    240243                                 http_incoming_data, req );
    241244       
    242         return FALSE;
     245        if( ssl_pending( req->ssl ) )
     246                return http_incoming_data( data, source, cond );
     247        else
     248                return FALSE;
    243249
    244250got_reply:
     
    275281       
    276282        *end1 = 0;
     283       
     284        if( getenv( "BITLBEE_DEBUG" ) )
     285                printf( "HTTP response headers:\n%s\n", req->reply_headers );
    277286       
    278287        if( evil_server )
     
    314323        }
    315324       
    316         if( ( req->status_code == 301 || req->status_code == 302 ) && req->redir_ttl-- > 0 )
     325        if( ( ( req->status_code >= 301 && req->status_code <= 303 ) ||
     326              req->status_code == 307 ) && req->redir_ttl-- > 0 )
    317327        {
    318328                char *loc, *new_request, *new_host;
     
    354364                        url_t *url;
    355365                        char *s;
     366                        const char *new_method;
    356367                       
    357368                        s = strstr( loc, "\r\n" );
     
    369380                        }
    370381                       
    371                         /* Okay, this isn't fun! We have to rebuild the request... :-( */
    372                         new_request = g_malloc( req->request_length + strlen( url->file ) );
    373                        
    374                         /* So, now I just allocated enough memory, so I'm
    375                            going to use strcat(), whether you like it or not. :-) */
    376                        
    377                         sprintf( new_request, "GET %s HTTP/1.0", url->file );
    378                        
    379                         s = strstr( req->request, "\r\n" );
    380                         if( s == NULL )
     382                        /* Find all headers and, if necessary, the POST request contents.
     383                           Skip the old Host: header though. This crappy code here means
     384                           anything using this http_client MUST put the Host: header at
     385                           the top. */
     386                        if( !( ( s = strstr( req->request, "\r\nHost: " ) ) &&
     387                               ( s = strstr( s + strlen( "\r\nHost: " ), "\r\n" ) ) ) )
    381388                        {
    382389                                req->status_string = g_strdup( "Error while rebuilding request string" );
    383                                 g_free( new_request );
    384390                                g_free( url );
    385391                                goto cleanup;
    386392                        }
    387393                       
    388                         strcat( new_request, s );
     394                        /* More or less HTTP/1.0 compliant, from my reading of RFC 2616.
     395                           Always perform a GET request unless we received a 301. 303 was
     396                           meant for this but it's HTTP/1.1-only and we're specifically
     397                           speaking HTTP/1.0. ...
     398                           
     399                           Well except someone at identi.ca's didn't bother reading any
     400                           RFCs and just return HTTP/1.1-specific status codes to HTTP/1.0
     401                           requests. Fuckers. So here we are, handle 301..303,307. */
     402                        if( strncmp( req->request, "GET", 3 ) == 0 )
     403                                /* GETs never become POSTs. */
     404                                new_method = "GET";
     405                        else if( req->status_code == 302 || req->status_code == 303 )
     406                                /* 302 de-facto becomes GET, 303 as specified by RFC 2616#10.3.3 */
     407                                new_method = "GET";
     408                        else
     409                                /* 301 de-facto should stay POST, 307 specifally RFC 2616#10.3.8 */
     410                                new_method = "POST";
     411                       
     412                        /* Okay, this isn't fun! We have to rebuild the request... :-( */
     413                        new_request = g_strdup_printf( "%s %s HTTP/1.0\r\nHost: %s%s",
     414                                                       new_method, url->file, url->host, s );
     415                       
    389416                        new_host = g_strdup( url->host );
    390417                        new_port = url->port;
    391418                        new_proto = url->proto;
     419                       
     420                        /* If we went from POST to GET, truncate the request content. */
     421                        if( new_request[0] != req->request[0] && new_request[0] == 'G' &&
     422                            ( s = strstr( new_request, "\r\n\r\n" ) ) )
     423                                s[4] = '\0';
    392424                       
    393425                        g_free( url );
     
    402434                req->ssl = NULL;
    403435               
     436                if( getenv( "BITLBEE_DEBUG" ) )
     437                        printf( "New headers for redirected HTTP request:\n%s\n", new_request );
     438       
    404439                if( new_proto == PROTO_HTTPS )
    405440                {
     
    443478                closesocket( req->fd );
    444479       
     480        if( getenv( "BITLBEE_DEBUG" ) && req )
     481                printf( "Finishing HTTP request with status: %s\n",
     482                        req->status_string ? req->status_string : "NULL" );
     483       
    445484        req->func( req );
    446485        http_free( req );
  • lib/ssl_client.h

    r87dddee r6e9ae72  
    6363G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
    6464
    65 /* See ssl_openssl.c for an explanation. */
     65/* Now needed by most SSL libs. See for more info:
     66   http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
     67   http://www.openssl.org/docs/ssl/SSL_pending.html
     68   
     69   Required because OpenSSL empties the TCP buffer completely but doesn't
     70   necessarily give us all the unencrypted data. Or maybe you didn't ask
     71   for all of it because your buffer is too small.
     72   
     73   Returns 0 if there's nothing left, 1 if there's more data. */
    6674G_MODULE_EXPORT int ssl_pending( void *conn );
    6775
  • lib/ssl_gnutls.c

    r87dddee r6e9ae72  
    4545#endif
    4646
     47#define SSLDEBUG 0
     48
    4749struct scd
    4850{
     
    135137        gnutls_certificate_allocate_credentials( &conn->xcred );
    136138        gnutls_init( &conn->session, GNUTLS_CLIENT );
    137         gnutls_transport_set_lowat( conn->session, 1 );
     139#if GNUTLS_VERSION_NUMBER < 0x020c00
     140        gnutls_transport_set_lowat( conn->session, 0 );
     141#endif
    138142        gnutls_set_default_priority( conn->session );
    139143        gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred );
     
    187191        {
    188192                ssl_errno = SSL_NOHANDSHAKE;
    189                 return( -1 );
     193                return -1;
    190194        }
    191195       
     
    196200                ssl_errno = SSL_AGAIN;
    197201       
    198         if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 1, buf, st );
     202        if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st );
    199203       
    200204        return st;
     
    208212        {
    209213                ssl_errno = SSL_NOHANDSHAKE;
    210                 return( -1 );
     214                return -1;
    211215        }
    212216       
     
    217221                ssl_errno = SSL_AGAIN;
    218222       
    219         if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 1, buf, st );
     223        if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st );
    220224       
    221225        return st;
    222226}
    223227
    224 /* See ssl_openssl.c for an explanation. */
    225228int ssl_pending( void *conn )
    226229{
    227         return 0;
     230        if( conn == NULL )
     231                return 0;
     232       
     233        if( !((struct scd*)conn)->established )
     234        {
     235                ssl_errno = SSL_NOHANDSHAKE;
     236                return 0;
     237        }
     238       
     239        return gnutls_record_check_pending( ((struct scd*)conn)->session ) != 0;
    228240}
    229241
  • lib/ssl_nss.c

    r87dddee r6e9ae72  
    207207}
    208208
    209 /* See ssl_openssl.c for an explanation. */
    210209int ssl_pending( void *conn )
    211210{
  • lib/ssl_openssl.c

    r87dddee r6e9ae72  
    241241}
    242242
    243 /* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info:
    244    http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
    245    http://www.openssl.org/docs/ssl/SSL_pending.html
    246    
    247    Required because OpenSSL empties the TCP buffer completely but doesn't
    248    necessarily give us all the unencrypted data.
    249    
    250    Returns 0 if there's nothing left or if we don't have to care (GnuTLS),
    251    1 if there's more data. */
    252243int ssl_pending( void *conn )
    253244{
  • lib/xmltree.c

    r87dddee r6e9ae72  
    323323}
    324324
    325 #ifdef DEBUG
    326325void xt_print( struct xt_node *node )
    327326{
     
    331330        /* Indentation */
    332331        for( c = node; c->parent; c = c->parent )
    333                 printf( "    " );
     332                fprintf( stderr, "    " );
    334333       
    335334        /* Start the tag */
    336         printf( "<%s", node->name );
     335        fprintf( stderr, "<%s", node->name );
    337336       
    338337        /* Print the attributes */
     
    340339        {
    341340                char *v = g_markup_escape_text( node->attr[i].value, -1 );
    342                 printf( " %s=\"%s\"", node->attr[i].key, v );
     341                fprintf( stderr, " %s=\"%s\"", node->attr[i].key, v );
    343342                g_free( v );
    344343        }
     
    349348        if( node->text == NULL && node->children == NULL )
    350349        {
    351                 printf( "/>\n" );
     350                fprintf( stderr, "/>\n" );
    352351                return;
    353352                /* Then we're finished! */
     
    355354       
    356355        /* Otherwise... */
    357         printf( ">" );
     356        fprintf( stderr, ">" );
    358357       
    359358        /* Only print the text if it contains more than whitespace (TEST). */
     
    364363                {
    365364                        char *v = g_markup_escape_text( node->text, -1 );
    366                         printf( "%s", v );
     365                        fprintf( stderr, "%s", v );
    367366                        g_free( v );
    368367                }
     
    370369       
    371370        if( node->children )
    372                 printf( "\n" );
     371                fprintf( stderr, "\n" );
    373372       
    374373        for( c = node->children; c; c = c->next )
     
    377376        if( node->children )
    378377                for( c = node; c->parent; c = c->parent )
    379                         printf( "    " );
     378                        fprintf( stderr, "    " );
    380379       
    381380        /* Non-empty tag is now finished. */
    382         printf( "</%s>\n", node->name );
    383 }
    384 #endif
     381        fprintf( stderr, "</%s>\n", node->name );
     382}
    385383
    386384struct xt_node *xt_dup( struct xt_node *node )
     
    557555}
    558556
     557/* Strip a few non-printable characters that aren't allowed in XML streams
     558   (and upset some XMPP servers for example). */
     559void xt_strip_text( char *in )
     560{
     561        char *out = in;
     562        static const char nonprint[32] = {
     563                0, 0, 0, 0, 0, 0, 0, 0, /* 0..7 */
     564                0, 1, 1, 0, 0, 1, 0, 0, /* 9 (tab), 10 (\n), 13 (\r) */
     565        };
     566       
     567        if( !in )
     568                return;
     569
     570        while( *in )
     571        {
     572                if( (unsigned int) *in >= ' ' || nonprint[(unsigned int) *in] )
     573                        *out ++ = *in;
     574                in ++;
     575        }
     576        *out = *in;
     577}
     578
    559579struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children )
    560580{
     
    568588        if( text )
    569589        {
    570                 node->text_len = strlen( text );
    571                 node->text = g_memdup( text, node->text_len + 1 );
     590                node->text = g_strdup( text );
     591                xt_strip_text( node->text );
     592                node->text_len = strlen( node->text );
    572593        }
    573594       
  • nick.c

    r87dddee r6e9ae72  
    243243                        int i;
    244244                       
    245                         irc_usermsg( irc, "Warning: Almost had an infinite loop in nick_get()! "
     245                        irc_rootmsg( irc, "Warning: Almost had an infinite loop in nick_get()! "
    246246                                          "This used to be a fatal BitlBee bug, but we tried to fix it. "
    247247                                          "This message should *never* appear anymore. "
     
    249249                                          "Please send all the following lines in your report:" );
    250250                       
    251                         irc_usermsg( irc, "Trying to get a sane nick for handle %s", bu->handle );
     251                        irc_rootmsg( irc, "Trying to get a sane nick for handle %s", bu->handle );
    252252                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
    253                                 irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
    254                        
    255                         irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "
     253                                irc_rootmsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
     254                       
     255                        irc_rootmsg( irc, "FAILED. Returning an insane nick now. Things might break. "
    256256                                          "Good luck, and please don't forget to paste the lines up here "
    257257                                          "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
  • otr.c

    r87dddee r6e9ae72  
    88  OTR support (cf. http://www.cypherpunks.ca/otr/)
    99 
    10   (c) 2008-2010 Sven Moritz Hallberg <pesco@khjk.org>
     10  (c) 2008-2011 Sven Moritz Hallberg <pesco@khjk.org>
    1111  (c) 2008 funded by stonedcoder.org
    1212   
     
    163163                const char *secret);
    164164
     165/* update flags within the irc_user structure to reflect OTR status of context */
     166void otr_update_uflags(ConnContext *context, irc_user_t *u);
     167
    165168/* update op/voice flag of given user according to encryption state and settings
    166169   returns 0 if neither op_buddies nor voice_buddies is set to "encrypted",
     
    182185/* find a private key by fingerprint prefix (given as any number of hex strings) */
    183186OtrlPrivKey *match_privkey(irc_t *irc, const char **args);
     187
     188/* check whether a string is safe to use in a path component */
     189int strsane(const char *s);
    184190
    185191/* functions to be called for certain events */
     
    237243        l = g_slist_prepend( l, "always" );
    238244        s->eval_data = l;
     245
     246        s = set_add( &irc->b->set, "otr_does_html", "true", set_eval_bool, irc );
    239247       
    240248        return TRUE;
     
    270278        int kg=0;
    271279
    272         g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, irc->user->nick);
    273         e = otrl_privkey_read(irc->otr->us, s);
    274         if(e && e!=enoent) {
    275                 irc_usermsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
    276         }
    277         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
    278         e = otrl_privkey_read_fingerprints(irc->otr->us, s, NULL, NULL);
    279         if(e && e!=enoent) {
    280                 irc_usermsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
     280        if(strsane(irc->user->nick)) {
     281                g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, irc->user->nick);
     282                e = otrl_privkey_read(irc->otr->us, s);
     283                if(e && e!=enoent) {
     284                        irc_rootmsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
     285                }
     286                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
     287                e = otrl_privkey_read_fingerprints(irc->otr->us, s, NULL, NULL);
     288                if(e && e!=enoent) {
     289                        irc_rootmsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
     290                }
    281291        }
    282292       
     
    286296        }
    287297        if(kg) {
    288                 irc_usermsg(irc, "Notice: "
     298                irc_rootmsg(irc, "Notice: "
    289299                        "The accounts above do not have OTR encryption keys associated with them, yet. "
    290300                        "These keys are now being generated in the background. "
     
    301311        gcry_error_t e;
    302312
    303         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
    304         e = otrl_privkey_write_fingerprints(irc->otr->us, s);
    305         if(e) {
    306                 irc_usermsg(irc, "otr save: %s: %s", s, gcry_strerror(e));
    307         }
    308         chmod(s, 0600);
     313        if(strsane(irc->user->nick)) {
     314                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
     315                e = otrl_privkey_write_fingerprints(irc->otr->us, s);
     316                if(e) {
     317                        irc_rootmsg(irc, "otr save: %s: %s", s, gcry_strerror(e));
     318                }
     319                chmod(s, 0600);
     320        }
    309321}
    310322
     
    313325        char s[512];
    314326       
    315         g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, nick);
    316         unlink(s);
    317         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, nick);
    318         unlink(s);
     327        if(strsane(nick)) {
     328                g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, nick);
     329                unlink(s);
     330                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, nick);
     331                unlink(s);
     332        }
    319333}
    320334
     
    323337        char s[512], t[512];
    324338       
    325         g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, onick);
    326         g_snprintf(t, 511, "%s%s.otr_keys", global.conf->configdir, nnick);
    327         rename(s,t);
    328         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, onick);
    329         g_snprintf(t, 511, "%s%s.otr_fprints", global.conf->configdir, nnick);
    330         rename(s,t);
     339        if(strsane(nnick) && strsane(onick)) {
     340                g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, onick);
     341                g_snprintf(t, 511, "%s%s.otr_keys", global.conf->configdir, nnick);
     342                rename(s,t);
     343                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, onick);
     344                g_snprintf(t, 511, "%s%s.otr_fprints", global.conf->configdir, nnick);
     345                rename(s,t);
     346        }
    331347}
    332348
     
    343359        k = otrl_privkey_find(irc->otr->us, a->user, a->prpl->name);
    344360        if(k) {
    345                 irc_usermsg(irc, "otr: %s/%s ready", a->user, a->prpl->name);
     361                irc_rootmsg(irc, "otr: %s/%s ready", a->user, a->prpl->name);
    346362                return 0;
    347363        } if(keygen_in_progress(irc, a->user, a->prpl->name)) {
    348                 irc_usermsg(irc, "otr: keygen for %s/%s already in progress", a->user, a->prpl->name);
     364                irc_rootmsg(irc, "otr: keygen for %s/%s already in progress", a->user, a->prpl->name);
    349365                return 0;
    350366        } else {
    351                 irc_usermsg(irc, "otr: starting background keygen for %s/%s", a->user, a->prpl->name);
     367                irc_rootmsg(irc, "otr: starting background keygen for %s/%s", a->user, a->prpl->name);
    352368                otr_keygen(irc, a->user, a->prpl->name);
    353369                return 1;
     
    360376        char *newmsg = NULL;
    361377        OtrlTLV *tlvs = NULL;
    362         char *colormsg;
    363378        irc_t *irc = iu->irc;
    364379        struct im_connection *ic = iu->bu->ic;
     
    380395        } else if(!newmsg) {
    381396                /* this was a non-OTR message */
    382                 return g_strdup(msg);
     397                return msg;
    383398        } else {
    384399                /* OTR has processed this message */
    385400                ConnContext *context = otrl_context_find(irc->otr->us, iu->bu->handle,
    386401                        ic->acc->user, ic->acc->prpl->name, 0, NULL, NULL, NULL);
    387                 if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
    388                    set_getbool(&ic->bee->set, "otr_color_encrypted")) {
    389                         /* color according to f'print trust */
    390                         int color;
    391                         const char *trust = context->active_fingerprint->trust;
    392                         if(trust && trust[0] != '\0')
    393                                 color=3;   /* green */
    394                         else
    395                                 color=5;   /* red */
    396 
    397                         if(newmsg[0] == ',') {
    398                                 /* could be a problem with the color code */
    399                                 /* insert a space between color spec and message */
    400                                 colormsg = g_strdup_printf("\x03%.2d %s\x0F", color, newmsg);
    401                         } else {
    402                                 colormsg = g_strdup_printf("\x03%.2d%s\x0F", color, newmsg);
     402
     403                /* we're done with the original msg, which will be caller-freed. */
     404                /* NB: must not change the newmsg pointer, since we free it. */
     405                msg = newmsg;
     406
     407                if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
     408                        /* HTML decoding */
     409                        /* perform any necessary stripping that the top level would miss */
     410                        if(set_getbool(&ic->bee->set, "otr_does_html") &&
     411                           !(ic->flags & OPT_DOES_HTML) &&
     412                           set_getbool(&ic->bee->set, "strip_html")) {
     413                                strip_html(msg);
    403414                        }
    404                 } else {
    405                         colormsg = g_strdup(newmsg);
     415
     416                        /* coloring */
     417                        if(set_getbool(&ic->bee->set, "otr_color_encrypted")) {
     418                                int color;                /* color according to f'print trust */
     419                                char *pre="", *sep="";    /* optional parts */
     420                                const char *trust = context->active_fingerprint->trust;
     421
     422                                if(trust && trust[0] != '\0')
     423                                        color=3;   /* green */
     424                                else
     425                                        color=5;   /* red */
     426
     427                                /* in a query window, keep "/me " uncolored at the beginning */
     428                                if(g_strncasecmp(msg, "/me ", 4) == 0
     429                                   && irc_user_msgdest(iu) == irc->user->nick) {
     430                                        msg += 4;  /* skip */
     431                                        pre = "/me ";
     432                                }
     433
     434                                /* comma in first place could mess with the color code */
     435                                if(msg[0] == ',') {
     436                                    /* insert a space between color spec and message */
     437                                    sep = " ";
     438                                }
     439
     440                                msg = g_strdup_printf("%s\x03%.2d%s%s\x0F", pre,
     441                                        color, sep, msg);
     442                        }
     443                }
     444
     445                if(msg == newmsg) {
     446                        msg = g_strdup(newmsg);
    406447                }
    407448                otrl_message_free(newmsg);
    408                 return colormsg;
     449                return msg;
    409450        }
    410451}
     
    414455        int st;
    415456        char *otrmsg = NULL;
     457        char *emsg = msg;           /* the message as we hand it to libotr */
    416458        ConnContext *ctx = NULL;
    417459        irc_t *irc = iu->irc;
     
    422464                return msg;
    423465        }
    424        
    425         st = otrl_message_sending(irc->otr->us, &otr_ops, ic,
    426                 ic->acc->user, ic->acc->prpl->name, iu->bu->handle,
    427                 msg, NULL, &otrmsg, NULL, NULL);
    428         if(st) {
    429                 return NULL;
    430         }
    431466
    432467        ctx = otrl_context_find(irc->otr->us,
    433468                        iu->bu->handle, ic->acc->user, ic->acc->prpl->name,
    434469                        1, NULL, NULL, NULL);
     470
     471        /* HTML encoding */
     472        /* consider OTR plaintext to be HTML if otr_does_html is set */
     473        if(ctx && ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
     474           set_getbool(&ic->bee->set, "otr_does_html") &&
     475           (g_strncasecmp(msg, "<html>", 6) != 0)) {
     476                emsg = escape_html(msg);
     477        }
     478       
     479        st = otrl_message_sending(irc->otr->us, &otr_ops, ic,
     480                ic->acc->user, ic->acc->prpl->name, iu->bu->handle,
     481                emsg, NULL, &otrmsg, NULL, NULL);
     482        if(emsg != msg) {
     483                g_free(emsg);   /* we're done with this one */
     484        }
     485        if(st) {
     486                return NULL;
     487        }
    435488
    436489        if(otrmsg) {
     
    480533       
    481534        if(!cmd->command) {
    482                 irc_usermsg(irc, "%s: unknown subcommand \"%s\", see \x02help otr\x02",
     535                irc_rootmsg(irc, "%s: unknown subcommand \"%s\", see \x02help otr\x02",
    483536                        args[0], args[1]);
    484537                return;
     
    486539       
    487540        if(!args[cmd->required_parameters+1]) {
    488                 irc_usermsg(irc, "%s %s: not enough arguments (%d req.)",
     541                irc_rootmsg(irc, "%s %s: not enough arguments (%d req.)",
    489542                        args[0], args[1], cmd->required_parameters);
    490543                return;
     
    558611        if (strcmp(accountname, recipient) == 0) {
    559612                /* huh? injecting messages to myself? */
    560                 irc_usermsg(irc, "note to self: %s", message);
     613                irc_rootmsg(irc, "note to self: %s", message);
    561614        } else {
    562615                /* need to drop some consts here :-( */
     
    573626        char *msg = g_strdup(message);
    574627        irc_t *irc = ic->bee->ui_data;
     628        irc_user_t *u = peeruser(irc, username, protocol);
    575629
    576630        strip_html(msg);
    577         irc_usermsg(irc, "otr: %s", msg);
     631        if(u) {
     632                /* display as a notice from this particular user */
     633                irc_usernotice(u, "%s", msg);
     634        } else {
     635                irc_rootmsg(irc, "[otr] %s", msg);
     636        }
    578637
    579638        g_free(msg);
     
    587646        struct im_connection *ic = check_imc(opdata, accountname, protocol);
    588647        irc_t *irc = ic->bee->ui_data;
     648        irc_user_t *u = peeruser(irc, username, protocol);
    589649        char hunam[45];         /* anybody looking? ;-) */
    590650       
    591651        otrl_privkey_hash_to_human(hunam, fingerprint);
    592         irc_usermsg(irc, "new fingerprint for %s: %s",
    593                 peernick(irc, username, protocol), hunam);
     652        if(u) {
     653                irc_usernotice(u, "new fingerprint: %s", hunam);
     654        } else {
     655                /* this case shouldn't normally happen */
     656                irc_rootmsg(irc, "new fingerprint for %s/%s: %s",
     657                        username, protocol, hunam);
     658        }
    594659}
    595660
     
    608673        irc_user_t *u;
    609674        irc_t *irc = ic->bee->ui_data;
    610         const char *trust;
    611675
    612676        u = peeruser(irc, context->username, context->protocol);
     
    618682        }
    619683       
    620         trust = context->active_fingerprint->trust;
    621         if(trust && trust[0])
    622                 u->flags |= IRC_USER_OTR_ENCRYPTED | IRC_USER_OTR_TRUSTED;
    623         else
    624                 u->flags = ( u->flags & ~IRC_USER_OTR_TRUSTED ) | IRC_USER_OTR_ENCRYPTED;
    625         if(!otr_update_modeflags(irc, u))
    626                 irc_usermsg(irc, "conversation with %s is now off the record", u->nick);
     684        otr_update_uflags(context, u);
     685        if(!otr_update_modeflags(irc, u)) {
     686                char *trust = u->flags & IRC_USER_OTR_TRUSTED ? "trusted" : "untrusted!";
     687                irc_usernotice(u, "conversation is now off the record (%s)", trust);
     688        }
    627689}
    628690
     
    641703                return;
    642704        }
    643         u->flags &= ~( IRC_USER_OTR_ENCRYPTED | IRC_USER_OTR_TRUSTED );
     705        otr_update_uflags(context, u);
    644706        if(!otr_update_modeflags(irc, u))
    645                 irc_usermsg(irc, "conversation with %s is now in the clear", u->nick);
     707                irc_usernotice(u, "conversation is now in cleartext");
    646708}
    647709
     
    660722                return;
    661723        }
    662         if(context->active_fingerprint->trust[0])
    663                 u->flags |= IRC_USER_OTR_ENCRYPTED | IRC_USER_OTR_TRUSTED;
    664         else
    665                 u->flags = ( u->flags & ~IRC_USER_OTR_TRUSTED ) | IRC_USER_OTR_ENCRYPTED;
    666         if(!otr_update_modeflags(irc, u))
    667                 irc_usermsg(irc, "otr connection with %s has been refreshed", u->nick);
     724
     725        otr_update_uflags(context, u);
     726        if(!otr_update_modeflags(irc, u)) {
     727                char *trust = u->flags & IRC_USER_OTR_TRUSTED ? "trusted" : "untrusted!";
     728                irc_usernotice(u, "otr connection has been refreshed (%s)", trust);
     729        }
    668730}
    669731
     
    708770        u = irc_user_by_name(irc, args[1]);
    709771        if(!u || !u->bu || !u->bu->ic) {
    710                 irc_usermsg(irc, "%s: unknown user", args[1]);
     772                irc_rootmsg(irc, "%s: unknown user", args[1]);
    711773                return;
    712774        }
     
    733795        u = irc_user_by_name(irc, args[1]);
    734796        if(!u || !u->bu || !u->bu->ic) {
    735                 irc_usermsg(irc, "%s: unknown user", args[1]);
     797                irc_rootmsg(irc, "%s: unknown user", args[1]);
    736798                return;
    737799        }
    738800        if(!(u->bu->flags & BEE_USER_ONLINE)) {
    739                 irc_usermsg(irc, "%s is offline", args[1]);
     801                irc_rootmsg(irc, "%s is offline", args[1]);
    740802                return;
    741803        }
     
    764826        u = irc_user_by_name(irc, args[1]);
    765827        if(!u || !u->bu || !u->bu->ic) {
    766                 irc_usermsg(irc, "%s: unknown user", args[1]);
     828                irc_rootmsg(irc, "%s: unknown user", args[1]);
    767829                return;
    768830        }
     
    771833                u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    772834        if(!ctx) {
    773                 irc_usermsg(irc, "%s: no otr context with user", args[1]);
     835                irc_rootmsg(irc, "%s: no otr context with user", args[1]);
    774836                return;
    775837        }
     
    783845                       
    784846                        if(!*p || !*q) {
    785                                 irc_usermsg(irc, "failed: truncated fingerprint block %d", i+1);
     847                                irc_rootmsg(irc, "failed: truncated fingerprint block %d", i+1);
    786848                                return;
    787849                        }
     
    790852                        y = hexval(*q);
    791853                        if(x<0) {
    792                                 irc_usermsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+1, i+1);
     854                                irc_rootmsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+1, i+1);
    793855                                return;
    794856                        }
    795857                        if(y<0) {
    796                                 irc_usermsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+2, i+1);
     858                                irc_rootmsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+2, i+1);
    797859                                return;
    798860                        }
     
    803865        fp = otrl_context_find_fingerprint(ctx, raw, 0, NULL);
    804866        if(!fp) {
    805                 irc_usermsg(irc, "failed: no such fingerprint for %s", args[1]);
     867                irc_rootmsg(irc, "failed: no such fingerprint for %s", args[1]);
    806868        } else {
    807869                char *trust = args[7] ? args[7] : "affirmed";
    808870                otrl_context_set_trust(fp, trust);
    809                 irc_usermsg(irc, "fingerprint match, trust set to \"%s\"", trust);
     871                irc_rootmsg(irc, "fingerprint match, trust set to \"%s\"", trust);
    810872                if(u->flags & IRC_USER_OTR_ENCRYPTED)
    811873                        u->flags |= IRC_USER_OTR_TRUSTED;
     
    835897                        ctx = otrl_context_find(irc->otr->us, handle, myhandle, protocol, 0, NULL, NULL, NULL);
    836898                        if(!ctx) {
    837                                 irc_usermsg(irc, "no such context");
     899                                irc_rootmsg(irc, "no such context");
    838900                                g_free(arg);
    839901                                return;
     
    842904                        irc_user_t *u = irc_user_by_name(irc, args[1]);
    843905                        if(!u || !u->bu || !u->bu->ic) {
    844                                 irc_usermsg(irc, "%s: unknown user", args[1]);
     906                                irc_rootmsg(irc, "%s: unknown user", args[1]);
    845907                                g_free(arg);
    846908                                return;
     
    849911                                u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    850912                        if(!ctx) {
    851                                 irc_usermsg(irc, "no otr context with %s", args[1]);
     913                                irc_rootmsg(irc, "no otr context with %s", args[1]);
    852914                                g_free(arg);
    853915                                return;
     
    857919                /* show how we resolved the (nick) argument, if we did */
    858920                if(handle!=arg) {
    859                         irc_usermsg(irc, "%s is %s/%s; we are %s/%s to them", args[1],
     921                        irc_rootmsg(irc, "%s is %s/%s; we are %s/%s to them", args[1],
    860922                                ctx->username, ctx->protocol, ctx->accountname, ctx->protocol);
    861923                }
     
    872934        n = atoi(args[1]);
    873935        if(n<0 || (!n && strcmp(args[1], "0"))) {
    874                 irc_usermsg(irc, "%s: invalid account number", args[1]);
     936                irc_rootmsg(irc, "%s: invalid account number", args[1]);
    875937                return;
    876938        }
     
    879941        for(i=0; i<n && a; i++, a=a->next);
    880942        if(!a) {
    881                 irc_usermsg(irc, "%s: no such account", args[1]);
     943                irc_rootmsg(irc, "%s: no such account", args[1]);
    882944                return;
    883945        }
    884946       
    885947        if(keygen_in_progress(irc, a->user, a->prpl->name)) {
    886                 irc_usermsg(irc, "keygen for account %d already in progress", n);
     948                irc_rootmsg(irc, "keygen for account %d already in progress", n);
    887949                return;
    888950        }
     
    906968       
    907969        if(fp == fp->context->active_fingerprint) {
    908                 irc_usermsg(irc, "that fingerprint is active, terminate otr connection first");
     970                irc_rootmsg(irc, "that fingerprint is active, terminate otr connection first");
    909971                return;
    910972        }
     
    922984       
    923985        if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
    924                 irc_usermsg(irc, "active otr connection with %s, terminate it first",
     986                irc_rootmsg(irc, "active otr connection with %s, terminate it first",
    925987                        peernick(irc, ctx->username, ctx->protocol));
    926988                return;
     
    9541016               
    9551017                if(!args[3]) {
    956                         irc_usermsg(irc, "otr %s %s: not enough arguments (2 req.)", args[0], args[1]);
     1018                        irc_rootmsg(irc, "otr %s %s: not enough arguments (2 req.)", args[0], args[1]);
    9571019                        return;
    9581020                }
     
    9611023                u = irc_user_by_name(irc, args[2]);
    9621024                if(!u || !u->bu || !u->bu->ic) {
    963                         irc_usermsg(irc, "%s: unknown user", args[2]);
     1025                        irc_rootmsg(irc, "%s: unknown user", args[2]);
    9641026                        return;
    9651027                }
     
    9681030                        u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    9691031                if(!ctx) {
    970                         irc_usermsg(irc, "no otr context with %s", args[2]);
     1032                        irc_rootmsg(irc, "no otr context with %s", args[2]);
    9711033                        return;
    9721034                }
     
    9791041               
    9801042                if(fp == ctx->active_fingerprint) {
    981                         irc_usermsg(irc, "that fingerprint is active, terminate otr connection first");
     1043                        irc_rootmsg(irc, "that fingerprint is active, terminate otr connection first");
    9821044                        return;
    9831045                }
     
    10041066                u = irc_user_by_name(irc, args[2]);
    10051067                if(!u || !u->bu || !u->bu->ic) {
    1006                         irc_usermsg(irc, "%s: unknown user", args[2]);
     1068                        irc_rootmsg(irc, "%s: unknown user", args[2]);
    10071069                        return;
    10081070                }
     
    10111073                        u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    10121074                if(!ctx) {
    1013                         irc_usermsg(irc, "no otr context with %s", args[2]);
     1075                        irc_rootmsg(irc, "no otr context with %s", args[2]);
    10141076                        return;
    10151077                }
    10161078               
    10171079                if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
    1018                         irc_usermsg(irc, "active otr connection with %s, terminate it first", args[2]);
     1080                        irc_rootmsg(irc, "active otr connection with %s, terminate it first", args[2]);
    10191081                        return;
    10201082                }
     
    10491111        else
    10501112        {
    1051                 irc_usermsg(irc, "otr %s: unknown subcommand \"%s\", see \x02help otr forget\x02",
     1113                irc_rootmsg(irc, "otr %s: unknown subcommand \"%s\", see \x02help otr forget\x02",
    10521114                        args[0], args[1]);
    10531115        }
     
    10751137        if(!context) {
    10761138                /* huh? out of memory or what? */
    1077                 irc_usermsg(irc, "smp: failed to get otr context for %s", u->nick);
     1139                irc_rootmsg(irc, "smp: failed to get otr context for %s", u->nick);
    10781140                otrl_message_abort_smp(us, ops, u->bu->ic, context);
    10791141                otrl_sm_state_free(context->smstate);
     
    10831145
    10841146        if (context->smstate->sm_prog_state == OTRL_SMP_PROG_CHEATED) {
    1085                 irc_usermsg(irc, "smp %s: opponent violated protocol, aborting",
     1147                irc_rootmsg(irc, "smp %s: opponent violated protocol, aborting",
    10861148                        u->nick);
    10871149                otrl_message_abort_smp(us, ops, u->bu->ic, context);
     
    10931155        if (tlv) {
    10941156                if (nextMsg != OTRL_SMP_EXPECT1) {
    1095                         irc_usermsg(irc, "smp %s: spurious SMP1Q received, aborting", u->nick);
     1157                        irc_rootmsg(irc, "smp %s: spurious SMP1Q received, aborting", u->nick);
    10961158                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    10971159                        otrl_sm_state_free(context->smstate);
    10981160                } else {
    10991161                        char *question = g_strndup((char *)tlv->data, tlv->len);
    1100                         irc_usermsg(irc, "smp: initiated by %s with question: \x02\"%s\"\x02", u->nick,
     1162                        irc_rootmsg(irc, "smp: initiated by %s with question: \x02\"%s\"\x02", u->nick,
    11011163                                question);
    1102                         irc_usermsg(irc, "smp: respond with \x02otr smp %s <answer>\x02",
     1164                        irc_rootmsg(irc, "smp: respond with \x02otr smp %s <answer>\x02",
    11031165                                u->nick);
    11041166                        g_free(question);
     
    11091171        if (tlv) {
    11101172                if (nextMsg != OTRL_SMP_EXPECT1) {
    1111                         irc_usermsg(irc, "smp %s: spurious SMP1 received, aborting", u->nick);
     1173                        irc_rootmsg(irc, "smp %s: spurious SMP1 received, aborting", u->nick);
    11121174                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11131175                        otrl_sm_state_free(context->smstate);
    11141176                } else {
    1115                         irc_usermsg(irc, "smp: initiated by %s"
     1177                        irc_rootmsg(irc, "smp: initiated by %s"
    11161178                                " - respond with \x02otr smp %s <secret>\x02",
    11171179                                u->nick, u->nick);
     
    11221184        if (tlv) {
    11231185                if (nextMsg != OTRL_SMP_EXPECT2) {
    1124                         irc_usermsg(irc, "smp %s: spurious SMP2 received, aborting", u->nick);
     1186                        irc_rootmsg(irc, "smp %s: spurious SMP2 received, aborting", u->nick);
    11251187                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11261188                        otrl_sm_state_free(context->smstate);
     
    11331195        if (tlv) {
    11341196                if (nextMsg != OTRL_SMP_EXPECT3) {
    1135                         irc_usermsg(irc, "smp %s: spurious SMP3 received, aborting", u->nick);
     1197                        irc_rootmsg(irc, "smp %s: spurious SMP3 received, aborting", u->nick);
    11361198                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11371199                        otrl_sm_state_free(context->smstate);
     
    11401202                        if(context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) {
    11411203                                if(context->smstate->received_question) {
    1142                                         irc_usermsg(irc, "smp %s: correct answer, you are trusted",
     1204                                        irc_rootmsg(irc, "smp %s: correct answer, you are trusted",
    11431205                                                u->nick);
    11441206                                } else {
    1145                                         irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
     1207                                        irc_rootmsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
    11461208                                                u->nick);
    11471209                                }
    11481210                        } else {
    11491211                                if(context->smstate->received_question) {
    1150                                         irc_usermsg(irc, "smp %s: wrong answer, you are not trusted",
     1212                                        irc_rootmsg(irc, "smp %s: wrong answer, you are not trusted",
    11511213                                                u->nick);
    11521214                                } else {
    1153                                         irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
     1215                                        irc_rootmsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
    11541216                                                u->nick);
    11551217                                }
     
    11621224        if (tlv) {
    11631225                if (nextMsg != OTRL_SMP_EXPECT4) {
    1164                         irc_usermsg(irc, "smp %s: spurious SMP4 received, aborting", u->nick);
     1226                        irc_rootmsg(irc, "smp %s: spurious SMP4 received, aborting", u->nick);
    11651227                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11661228                        otrl_sm_state_free(context->smstate);
     
    11681230                        /* SMP4 received, otrl_message_receiving will have set fp trust */
    11691231                        if(context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) {
    1170                                 irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
     1232                                irc_rootmsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
    11711233                                        u->nick);
    11721234                        } else {
    1173                                 irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
     1235                                irc_rootmsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
    11741236                                        u->nick);
    11751237                        }
     
    11801242        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
    11811243        if (tlv) {
    1182                 irc_usermsg(irc, "smp: received abort from %s", u->nick);
     1244                irc_rootmsg(irc, "smp: received abort from %s", u->nick);
    11831245                otrl_sm_state_free(context->smstate);
    11841246                /* smp is in back in EXPECT1 */
     
    11951257        u = irc_user_by_name(irc, nick);
    11961258        if(!u || !u->bu || !u->bu->ic) {
    1197                 irc_usermsg(irc, "%s: unknown user", nick);
     1259                irc_rootmsg(irc, "%s: unknown user", nick);
    11981260                return;
    11991261        }
    12001262        if(!(u->bu->flags & BEE_USER_ONLINE)) {
    1201                 irc_usermsg(irc, "%s is offline", nick);
     1263                irc_rootmsg(irc, "%s is offline", nick);
    12021264                return;
    12031265        }
     
    12061268                u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    12071269        if(!ctx || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
    1208                 irc_usermsg(irc, "smp: otr inactive with %s, try \x02otr connect"
     1270                irc_rootmsg(irc, "smp: otr inactive with %s, try \x02otr connect"
    12091271                                " %s\x02", nick, nick);
    12101272                return;
     
    12211283        if(question) {
    12221284                /* this was 'otr smpq', just initiate */
    1223                 irc_usermsg(irc, "smp: initiating with %s...", u->nick);
     1285                irc_rootmsg(irc, "smp: initiating with %s...", u->nick);
    12241286                otrl_message_initiate_smp_q(irc->otr->us, &otr_ops, u->bu->ic, ctx,
    12251287                        question, (unsigned char *)secret, strlen(secret));
     
    12301292                   is completed or aborted! */
    12311293                if(ctx->smstate->secret == NULL) {
    1232                         irc_usermsg(irc, "smp: initiating with %s...", u->nick);
     1294                        irc_rootmsg(irc, "smp: initiating with %s...", u->nick);
    12331295                        otrl_message_initiate_smp(irc->otr->us, &otr_ops,
    12341296                                u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
     
    12371299                        /* if we're still in EXPECT1 but smstate is initialized, we must have
    12381300                           received the SMP1, so let's issue a response */
    1239                         irc_usermsg(irc, "smp: responding to %s...", u->nick);
     1301                        irc_rootmsg(irc, "smp: responding to %s...", u->nick);
    12401302                        otrl_message_respond_smp(irc->otr->us, &otr_ops,
    12411303                                u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
     
    13121374}
    13131375
     1376void otr_update_uflags(ConnContext *context, irc_user_t *u)
     1377{
     1378        const char *trust;
     1379
     1380        if(context->active_fingerprint) {
     1381                u->flags |= IRC_USER_OTR_ENCRYPTED;
     1382
     1383                trust = context->active_fingerprint->trust;
     1384                if(trust && trust[0])
     1385                        u->flags |= IRC_USER_OTR_TRUSTED;
     1386                else
     1387                        u->flags &= ~IRC_USER_OTR_TRUSTED;
     1388        } else {
     1389                u->flags &= ~IRC_USER_OTR_ENCRYPTED;
     1390        }
     1391}
     1392
    13141393int otr_update_modeflags(irc_t *irc, irc_user_t *u)
    13151394{
    1316         return 1;
     1395        return 0;
    13171396}
    13181397
     
    13351414                }
    13361415                if(fp == ctx->active_fingerprint) {
    1337                         irc_usermsg(irc, "    \x02%s (%s)\x02", human, trust);
     1416                        irc_rootmsg(irc, "    \x02%s (%s)\x02", human, trust);
    13381417                } else {
    1339                         irc_usermsg(irc, "    %s (%s)", human, trust);
     1418                        irc_rootmsg(irc, "    %s (%s)", human, trust);
    13401419                }
    13411420        }
    13421421        if(count==0)
    1343                 irc_usermsg(irc, "    (none)");
     1422                irc_rootmsg(irc, "    (none)");
    13441423}
    13451424
     
    13601439                       
    13611440                        if(n>=40) {
    1362                                 irc_usermsg(irc, "too many fingerprint digits given, expected at most 40");
     1441                                irc_rootmsg(irc, "too many fingerprint digits given, expected at most 40");
    13631442                                return NULL;
    13641443                        }
     
    13671446                                *(p++) = c;
    13681447                        } else {
    1369                                 irc_usermsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
     1448                                irc_rootmsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
    13701449                                return NULL;
    13711450                        }
     
    13881467        }
    13891468        if(!fp) {
    1390                 irc_usermsg(irc, "%s: no match", prefix);
     1469                irc_rootmsg(irc, "%s: no match", prefix);
    13911470                return NULL;
    13921471        }
     
    14011480        }
    14021481        if(fp2) {
    1403                 irc_usermsg(irc, "%s: multiple matches", prefix);
     1482                irc_rootmsg(irc, "%s: multiple matches", prefix);
    14041483                return NULL;
    14051484        }
     
    14241503                       
    14251504                        if(n>=40) {
    1426                                 irc_usermsg(irc, "too many fingerprint digits given, expected at most 40");
     1505                                irc_rootmsg(irc, "too many fingerprint digits given, expected at most 40");
    14271506                                return NULL;
    14281507                        }
     
    14311510                                *(p++) = c;
    14321511                        } else {
    1433                                 irc_usermsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
     1512                                irc_rootmsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
    14341513                                return NULL;
    14351514                        }
     
    14521531        }
    14531532        if(!k) {
    1454                 irc_usermsg(irc, "%s: no match", prefix);
     1533                irc_rootmsg(irc, "%s: no match", prefix);
    14551534                return NULL;
    14561535        }
     
    14651544        }
    14661545        if(k2) {
    1467                 irc_usermsg(irc, "%s: multiple matches", prefix);
     1546                irc_rootmsg(irc, "%s: multiple matches", prefix);
    14681547                return NULL;
    14691548        }
     
    14801559
    14811560        /* list all privkeys (including ones being generated) */
    1482         irc_usermsg(irc, "\x1fprivate keys:\x1f");
     1561        irc_rootmsg(irc, "\x1fprivate keys:\x1f");
    14831562        for(key=irc->otr->us->privkey_root; key; key=key->next) {
    14841563                const char *hash;
     
    14861565                switch(key->pubkey_type) {
    14871566                case OTRL_PUBKEY_TYPE_DSA:
    1488                         irc_usermsg(irc, "  %s/%s - DSA", key->accountname, key->protocol);
     1567                        irc_rootmsg(irc, "  %s/%s - DSA", key->accountname, key->protocol);
    14891568                        break;
    14901569                default:
    1491                         irc_usermsg(irc, "  %s/%s - type %d", key->accountname, key->protocol,
     1570                        irc_rootmsg(irc, "  %s/%s - type %d", key->accountname, key->protocol,
    14921571                                key->pubkey_type);
    14931572                }
     
    14981577                hash = otrl_privkey_fingerprint(irc->otr->us, human, key->accountname, key->protocol);
    14991578                if(hash) /* should always succeed */
    1500                         irc_usermsg(irc, "    %s", human);
     1579                        irc_rootmsg(irc, "    %s", human);
    15011580        }
    15021581        if(irc->otr->sent_accountname) {
    1503                 irc_usermsg(irc, "  %s/%s - DSA", irc->otr->sent_accountname,
     1582                irc_rootmsg(irc, "  %s/%s - DSA", irc->otr->sent_accountname,
    15041583                        irc->otr->sent_protocol);
    1505                 irc_usermsg(irc, "    (being generated)");
     1584                irc_rootmsg(irc, "    (being generated)");
    15061585        }
    15071586        for(kg=irc->otr->todo; kg; kg=kg->next) {
    1508                 irc_usermsg(irc, "  %s/%s - DSA", kg->accountname, kg->protocol);
    1509                 irc_usermsg(irc, "    (queued)");
     1587                irc_rootmsg(irc, "  %s/%s - DSA", kg->accountname, kg->protocol);
     1588                irc_rootmsg(irc, "    (queued)");
    15101589        }
    15111590        if(key == irc->otr->us->privkey_root &&
    15121591           !irc->otr->sent_accountname &&
    15131592           kg == irc->otr->todo)
    1514                 irc_usermsg(irc, "  (none)");
     1593                irc_rootmsg(irc, "  (none)");
    15151594
    15161595        /* list all contexts */
    1517         irc_usermsg(irc, "%s", "");
    1518         irc_usermsg(irc, "\x1f" "connection contexts:\x1f (bold=currently encrypted)");
     1596        irc_rootmsg(irc, "%s", "");
     1597        irc_rootmsg(irc, "\x1f" "connection contexts:\x1f (bold=currently encrypted)");
    15191598        for(ctx=irc->otr->us->context_root; ctx; ctx=ctx->next) {\
    15201599                irc_user_t *u;
     
    15301609               
    15311610                if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
    1532                         irc_usermsg(irc, "  \x02%s\x02", userstring);
     1611                        irc_rootmsg(irc, "  \x02%s\x02", userstring);
    15331612                } else {
    1534                         irc_usermsg(irc, "  %s", userstring);
     1613                        irc_rootmsg(irc, "  %s", userstring);
    15351614                }
    15361615               
     
    15381617        }
    15391618        if(ctx == irc->otr->us->context_root)
    1540                 irc_usermsg(irc, "  (none)");
     1619                irc_rootmsg(irc, "  (none)");
    15411620}
    15421621
     
    15451624        switch(ctx->otr_offer) {
    15461625        case OFFER_NOT:
    1547                 irc_usermsg(irc, "  otr offer status: none sent");
     1626                irc_rootmsg(irc, "  otr offer status: none sent");
    15481627                break;
    15491628        case OFFER_SENT:
    1550                 irc_usermsg(irc, "  otr offer status: awaiting reply");
     1629                irc_rootmsg(irc, "  otr offer status: awaiting reply");
    15511630                break;
    15521631        case OFFER_ACCEPTED:
    1553                 irc_usermsg(irc, "  otr offer status: accepted our offer");
     1632                irc_rootmsg(irc, "  otr offer status: accepted our offer");
    15541633                break;
    15551634        case OFFER_REJECTED:
    1556                 irc_usermsg(irc, "  otr offer status: ignored our offer");
     1635                irc_rootmsg(irc, "  otr offer status: ignored our offer");
    15571636                break;
    15581637        default:
    1559                 irc_usermsg(irc, "  otr offer status: %d", ctx->otr_offer);
     1638                irc_rootmsg(irc, "  otr offer status: %d", ctx->otr_offer);
    15601639        }
    15611640
    15621641        switch(ctx->msgstate) {
    15631642        case OTRL_MSGSTATE_PLAINTEXT:
    1564                 irc_usermsg(irc, "  connection state: cleartext");
     1643                irc_rootmsg(irc, "  connection state: cleartext");
    15651644                break;
    15661645        case OTRL_MSGSTATE_ENCRYPTED:
    1567                 irc_usermsg(irc, "  connection state: encrypted (v%d)", ctx->protocol_version);
     1646                irc_rootmsg(irc, "  connection state: encrypted (v%d)", ctx->protocol_version);
    15681647                break;
    15691648        case OTRL_MSGSTATE_FINISHED:
    1570                 irc_usermsg(irc, "  connection state: shut down");
     1649                irc_rootmsg(irc, "  connection state: shut down");
    15711650                break;
    15721651        default:
    1573                 irc_usermsg(irc, "  connection state: %d", ctx->msgstate);
    1574         }
    1575 
    1576         irc_usermsg(irc, "  fingerprints: (bold=active)");     
     1652                irc_rootmsg(irc, "  connection state: %d", ctx->msgstate);
     1653        }
     1654
     1655        irc_rootmsg(irc, "  fingerprints: (bold=active)");     
    15771656        show_fingerprints(irc, ctx);
    15781657}
     
    16141693               
    16151694                if(pipe(to) < 0 || pipe(from) < 0) {
    1616                         irc_usermsg(irc, "otr keygen: couldn't create pipe: %s", strerror(errno));
     1695                        irc_rootmsg(irc, "otr keygen: couldn't create pipe: %s", strerror(errno));
    16171696                        return;
    16181697                }
     
    16211700                fromf = fdopen(from[0], "r");
    16221701                if(!tof || !fromf) {
    1623                         irc_usermsg(irc, "otr keygen: couldn't streamify pipe: %s", strerror(errno));
     1702                        irc_rootmsg(irc, "otr keygen: couldn't streamify pipe: %s", strerror(errno));
    16241703                        return;
    16251704                }
     
    16271706                p = fork();
    16281707                if(p<0) {
    1629                         irc_usermsg(irc, "otr keygen: couldn't fork: %s", strerror(errno));
     1708                        irc_rootmsg(irc, "otr keygen: couldn't fork: %s", strerror(errno));
    16301709                        return;
    16311710                }
     
    17071786        myfgets(msg, 512, irc->otr->from);
    17081787       
    1709         irc_usermsg(irc, "%s", msg);
     1788        irc_rootmsg(irc, "%s", msg);
    17101789        if(filename[0]) {
    1711                 char *kf = g_strdup_printf("%s%s.otr_keys", global.conf->configdir, irc->user->nick);
    1712                 char *tmp = g_strdup_printf("%s.new", kf);
    1713                 copyfile(filename, tmp);
    1714                 unlink(filename);
    1715                 rename(tmp,kf);
    1716                 otrl_privkey_read(irc->otr->us, kf);
    1717                 g_free(kf);
    1718                 g_free(tmp);
     1790                if(strsane(irc->user->nick)) {
     1791                        char *kf = g_strdup_printf("%s%s.otr_keys", global.conf->configdir, irc->user->nick);
     1792                        char *tmp = g_strdup_printf("%s.new", kf);
     1793                        copyfile(filename, tmp);
     1794                        unlink(filename);
     1795                        rename(tmp,kf);
     1796                        otrl_privkey_read(irc->otr->us, kf);
     1797                        g_free(kf);
     1798                        g_free(tmp);
     1799                } else {
     1800                        otrl_privkey_read(irc->otr->us, filename);
     1801                        unlink(filename);
     1802                }
    17191803        }
    17201804       
     
    17811865       
    17821866        if(keygen_in_progress(irc, acc->user, acc->prpl->name)) {
    1783                 irc_usermsg(irc, "keygen for %s/%s already in progress",
     1867                irc_rootmsg(irc, "keygen for %s/%s already in progress",
    17841868                        acc->user, acc->prpl->name);
    17851869        } else {
    1786                 irc_usermsg(irc, "starting background keygen for %s/%s",
     1870                irc_rootmsg(irc, "starting background keygen for %s/%s",
    17871871                        acc->user, acc->prpl->name);
    1788                 irc_usermsg(irc, "you will be notified when it completes");
     1872                irc_rootmsg(irc, "you will be notified when it completes");
    17891873                otr_keygen(irc, acc->user, acc->prpl->name);
    17901874        }
    17911875}
     1876
     1877/* check whether a string is safe to use in a path component */
     1878int strsane(const char *s)
     1879{
     1880        return strpbrk(s, "/\\") == NULL;
     1881}
     1882
     1883/* vim: set noet ts=4 sw=4: */
  • protocols/jabber/io.c

    r87dddee r6e9ae72  
    212212                                   this is an old server that can't do SASL
    213213                                   authentication. */
    214                                 if( !sasl_supported( ic ) )
     214                                if( !set_getbool( &ic->acc->set, "sasl") || !sasl_supported( ic ) )
    215215                                {
    216216                                        /* If there's no version= tag, we suppose
     
    375375           other way. jabber.com doesn't seem to do SASL while it pretends
    376376           to be XMPP 1.0 compliant! */
    377         else if( !( jd->flags & JFLAG_AUTHENTICATED ) && sasl_supported( ic ) )
     377        else if( !( jd->flags & JFLAG_AUTHENTICATED ) && set_getbool( &ic->acc->set, "sasl") && sasl_supported( ic ) )
    378378        {
    379379                if( !jabber_init_iq_auth( ic ) )
  • protocols/jabber/jabber.c

    r87dddee r6e9ae72  
    8484        s->flags |= ACC_SET_OFFLINE_ONLY;
    8585       
     86        s = set_add( &acc->set, "sasl", "true", set_eval_bool, acc );
     87        s->flags |= ACC_SET_OFFLINE_ONLY | SET_HIDDEN_DEFAULT;
     88
    8689        s = set_add( &acc->set, "user_agent", "BitlBee", NULL, acc );
    8790       
  • protocols/jabber/s5bytestream.c

    r87dddee r6e9ae72  
    877877
    878878        if( ( ( host = strchr( proxy, ',' ) ) == 0 ) ||
    879              ( ( port = strchr( host+1, ',' ) ) == 0 ) ) {
     879            ( ( port = strchr( host+1, ',' ) ) == 0 ) )
     880        {
    880881                imcb_log( ic, "Error parsing proxy setting: \"%s\" (ignored)", proxy );
    881882                return NULL;
     
    889890        sh->jid = g_strdup( jid );
    890891        sh->host = g_strdup( host );
    891         strcpy( sh->port, port );
     892        g_snprintf( sh->port, sizeof( sh->port ), "%s", port );
    892893
    893894        return sh;
     
    915916                                sh->jid = g_strdup( tf->ini_jid );
    916917                                sh->host = g_strdup( host );
    917                                 strcpy( sh->port, port );
     918                                g_snprintf( sh->port, sizeof( sh->port ), "%s", port );
    918919                                bt->streamhosts = g_slist_append( bt->streamhosts, sh );
    919920
  • protocols/msn/ns.c

    r87dddee r6e9ae72  
    480480                else
    481481                {
    482                         imcb_error( ic, "Session terminated by remote server (reason unknown)" );
     482                        imcb_error( ic, "Session terminated by remote server (%s)",
     483                                    cmd[1] ? cmd[1] : "reason unknown)" );
    483484                }
    484485               
  • protocols/msn/sb.c

    r87dddee r6e9ae72  
    308308        struct msn_switchboard *sb = data;
    309309        struct im_connection *ic;
    310         struct msn_data *md;
    311310        char buf[1024];
    312311       
     
    316315       
    317316        ic = sb->ic;
    318         md = ic->proto_data;
    319317       
    320318        if( source != sb->fd )
     
    675673        struct im_connection *ic = sb->ic;
    676674        char *body;
    677         int blen = 0;
    678675       
    679676        if( !num_parts )
     
    681678       
    682679        if( ( body = strstr( msg, "\r\n\r\n" ) ) )
    683         {
    684680                body += 4;
    685                 blen = msglen - ( body - msg );
    686         }
    687681       
    688682        if( strcmp( cmd[0], "MSG" ) == 0 )
  • protocols/msn/soap.c

    r87dddee r6e9ae72  
    210210{
    211211        char *s;
    212         int st;
    213212       
    214213        if( !getenv( "BITLBEE_DEBUG" ) )
    215214                return;
    216215       
    217         if( ( s = strstr( headers, "\r\n\r\n" ) ) )
    218                 st = write( 1, s, s - headers + 4 );
    219         else
    220                 st = write( 1, headers, strlen( headers ) );
    221        
    222 #ifdef DEBUG
     216        if( headers )
     217        {
     218                if( ( s = strstr( headers, "\r\n\r\n" ) ) )
     219                        write( 2, headers, s - headers + 4 );
     220                else
     221                        write( 2, headers, strlen( headers ) );
     222        }
     223       
     224        if( payload )
    223225        {
    224226                struct xt_node *xt = xt_from_string( payload );
     
    227229                xt_free_node( xt );
    228230        }
    229 #endif
    230231}
    231232
     
    661662       
    662663        if( getenv( "BITLBEE_DEBUG" ) )
    663                 printf( "%p %s %d\n", bu, handle, bd->flags );
     664                fprintf( stderr, "%p %s %d\n", bu, handle, bd->flags );
    664665       
    665666        return XT_HANDLED;
     
    808809       
    809810        if( getenv( "BITLBEE_DEBUG" ) )
    810                 printf( "%s %s\n", id, name );
     811                fprintf( stderr, "%s %s\n", id, name );
    811812       
    812813        return XT_HANDLED;
     
    869870       
    870871        if( getenv( "BITLBEE_DEBUG" ) )
    871                 printf( "%s %s %s %s\n", id, type, handle, display_name );
     872                fprintf( stderr, "%s %s %s %s\n", id, type, handle, display_name );
    872873       
    873874        return XT_HANDLED;
  • protocols/nogaim.c

    r87dddee r6e9ae72  
    216216        if( a )
    217217                /* FIXME(wilmer): ui_log callback or so */
    218                 irc_usermsg( ic->bee->ui_data, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text );
     218                irc_rootmsg( ic->bee->ui_data, "%s - %s", ic->acc->tag, text );
    219219        else
    220                 irc_usermsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text );
     220                irc_rootmsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text );
    221221       
    222222        g_free( text );
  • protocols/oscar/chat.c

    r87dddee r6e9ae72  
    384384        char *roomname = NULL;
    385385        struct aim_chat_roominfo roominfo;
    386         guint16 tlvcount = 0;
    387386        aim_tlvlist_t *tlvlist;
    388387        char *roomdesc = NULL;
     
    401400        }
    402401
    403         tlvcount = aimbs_get16(bs);
     402        aimbs_get16(bs); /* tlv count */
    404403
    405404        /*
  • protocols/oscar/chatnav.c

    r87dddee r6e9ae72  
    139139                 * Type 0x0002: Unknown
    140140                 */
    141                 if (aim_gettlv(innerlist, 0x0002, 1)) {
    142                         guint16 classperms;
    143 
    144                         classperms = aim_gettlv16(innerlist, 0x0002, 1);
    145                        
    146                 }
     141                if (aim_gettlv(innerlist, 0x0002, 1))
     142                        ;
    147143
    148144                /*
     
    205201                 */
    206202                if (aim_gettlv(innerlist, 0x00d5, 1)) {
    207                         guint8 createperms;
    208 
    209                         createperms = aim_gettlv8(innerlist, 0x00d5, 1);
     203                        aim_gettlv8(innerlist, 0x00d5, 1); /* createperms */
    210204                }
    211205
  • protocols/oscar/icq.c

    r87dddee r6e9ae72  
    235235        aim_tlv_t *datatlv;
    236236        aim_bstream_t qbs;
    237         guint32 ouruin;
    238         guint16 cmdlen, cmd, reqid;
     237        guint16 cmd, reqid;
    239238
    240239        if (!(tl = aim_readtlvchain(bs)) || !(datatlv = aim_gettlv(tl, 0x0001, 1))) {
     
    246245        aim_bstream_init(&qbs, datatlv->value, datatlv->length);
    247246
    248         cmdlen = aimbs_getle16(&qbs);
    249         ouruin = aimbs_getle32(&qbs);
     247        aimbs_getle16(&qbs); /* cmdlen */
     248        aimbs_getle32(&qbs); /* ouruin */
    250249        cmd = aimbs_getle16(&qbs);
    251250        reqid = aimbs_getle16(&qbs);
  • protocols/oscar/im.c

    r87dddee r6e9ae72  
    919919        int i, ret = 0;
    920920        aim_rxcallback_t userfunc;
    921         guint8 cookie[8];
    922921        guint16 channel;
    923922        aim_tlvlist_t *tlvlist;
     
    931930        /* ICBM Cookie. */
    932931        for (i = 0; i < 8; i++)
    933                 cookie[i] = aimbs_get8(bs);
     932                aimbs_get8(bs);
    934933
    935934        /* Channel ID */
     
    14141413{
    14151414        guint16 hdrlen, msglen, dc;
    1416         guint8 msgtype, msgflags;
     1415        guint8 msgtype;
    14171416    guint8 *plugin;
    14181417    int i = 0, tmp = 0;
     
    14421441
    14431442        msgtype = aimbs_getle8(servdata);
    1444         msgflags = aimbs_getle8(servdata);
     1443        aimbs_getle8(servdata); /* msgflags */
    14451444
    14461445        aim_bstream_advance(servdata, 0x04); /* status code and priority code */
  • protocols/oscar/misc.c

    r87dddee r6e9ae72  
    310310{
    311311        aim_frame_t *fr;
    312         aim_snacid_t snacid;
    313312        aim_tlvlist_t *tl = NULL;
    314313
     
    330329                return -ENOMEM;
    331330
    332         snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);
     331        aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);
    333332
    334333        aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0);
  • protocols/oscar/oscar.c

    r87dddee r6e9ae72  
    10721072static void gaim_icq_authgrant(void *data_) {
    10731073        struct icq_auth *data = data_;
    1074         char *uin, message;
     1074        char *uin;
    10751075        struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
    10761076       
    10771077        uin = g_strdup_printf("%u", data->uin);
    1078         message = 0;
    10791078        aim_ssi_auth_reply(od->sess, od->conn, uin, 1, "");
     1079        // char *message = 0;
    10801080        // aim_send_im_ch4(od->sess, uin, AIM_ICQMSG_AUTHGRANTED, &message);
    10811081        imcb_ask_add(data->ic, uin, NULL);
     
    12191219static int gaim_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...) {
    12201220        va_list ap;
    1221         guint16 chan, nummissed, reason;
     1221        guint16 nummissed, reason;
    12221222        aim_userinfo_t *userinfo;
    12231223
    12241224        va_start(ap, fr);
    1225         chan = (guint16)va_arg(ap, unsigned int);
     1225        va_arg(ap, unsigned int); /* chan */
    12261226        userinfo = va_arg(ap, aim_userinfo_t *);
    12271227        nummissed = (guint16)va_arg(ap, unsigned int);
     
    13351335
    13361336static int gaim_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...) {
    1337         char *msg;
    13381337        guint16 id;
    13391338        va_list ap;
     
    13411340        va_start(ap, fr);
    13421341        id  = (guint16)va_arg(ap, unsigned int);
    1343         msg = va_arg(ap, char *);
     1342        va_arg(ap, char *); /* msg */
    13441343        va_end(ap);
    13451344
     
    13611360        switch(type) {
    13621361                case 0x0002: {
    1363                         guint8 maxrooms;
    1364                         struct aim_chat_exchangeinfo *exchanges;
    1365                         int exchangecount; // i;
    1366 
    1367                         maxrooms = (guint8)va_arg(ap, unsigned int);
    1368                         exchangecount = va_arg(ap, int);
    1369                         exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
     1362                        va_arg(ap, unsigned int); /* maxrooms */
     1363                        va_arg(ap, int); /* exchangecount */
     1364                        va_arg(ap, struct aim_chat_exchangeinfo *); /* exchanges */
    13701365                        va_end(ap);
    13711366
     
    13801375                        break;
    13811376                case 0x0008: {
    1382                         char *fqcn, *name, *ck;
    1383                         guint16 instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
    1384                         guint8 createperms;
    1385                         guint32 createtime;
    1386 
    1387                         fqcn = va_arg(ap, char *);
     1377                        char *ck;
     1378                        guint16 instance, exchange;
     1379
     1380                        va_arg(ap, char *); /* fqcn */
    13881381                        instance = (guint16)va_arg(ap, unsigned int);
    13891382                        exchange = (guint16)va_arg(ap, unsigned int);
    1390                         flags = (guint16)va_arg(ap, unsigned int);
    1391                         createtime = va_arg(ap, guint32);
    1392                         maxmsglen = (guint16)va_arg(ap, unsigned int);
    1393                         maxoccupancy = (guint16)va_arg(ap, unsigned int);
    1394                         createperms = (guint8)va_arg(ap, int);
    1395                         unknown = (guint16)va_arg(ap, unsigned int);
    1396                         name = va_arg(ap, char *);
     1383                        va_arg(ap, unsigned int); /* flags */
     1384                        va_arg(ap, guint32); /* createtime */
     1385                        va_arg(ap, unsigned int); /* maxmsglen */
     1386                        va_arg(ap, unsigned int); /* maxoccupancy */
     1387                        va_arg(ap, int); /* createperms */
     1388                        va_arg(ap, unsigned int); /* unknown */
     1389                        va_arg(ap, char *); /* name */
    13971390                        ck = va_arg(ap, char *);
    13981391                        va_end(ap);
     
    14561449static int gaim_chat_info_update(aim_session_t *sess, aim_frame_t *fr, ...) {
    14571450        va_list ap;
    1458         aim_userinfo_t *userinfo;
    1459         struct aim_chat_roominfo *roominfo;
    1460         char *roomname;
    1461         int usercount;
    1462         char *roomdesc;
    1463         guint16 unknown_c9, unknown_d2, unknown_d5, maxmsglen, maxvisiblemsglen;
    1464         guint32 creationtime;
     1451        guint16 maxmsglen, maxvisiblemsglen;
    14651452        struct im_connection *ic = sess->aux_data;
    14661453        struct chat_connection *ccon = find_oscar_chat_by_conn(ic, fr->conn);
    14671454
    14681455        va_start(ap, fr);
    1469         roominfo = va_arg(ap, struct aim_chat_roominfo *);
    1470         roomname = va_arg(ap, char *);
    1471         usercount= va_arg(ap, int);
    1472         userinfo = va_arg(ap, aim_userinfo_t *);
    1473         roomdesc = va_arg(ap, char *);
    1474         unknown_c9 = (guint16)va_arg(ap, int);
    1475         creationtime = (guint32)va_arg(ap, unsigned long);
     1456        va_arg(ap, struct aim_chat_roominfo *); /* roominfo */
     1457        va_arg(ap, char *); /* roomname */
     1458        va_arg(ap, int); /* usercount */
     1459        va_arg(ap, aim_userinfo_t *); /* userinfo */
     1460        va_arg(ap, char *); /* roomdesc */
     1461        va_arg(ap, int); /* unknown_c9 */
     1462        va_arg(ap, unsigned long); /* creationtime */
    14761463        maxmsglen = (guint16)va_arg(ap, int);
    1477         unknown_d2 = (guint16)va_arg(ap, int);
    1478         unknown_d5 = (guint16)va_arg(ap, int);
     1464        va_arg(ap, int); /* unknown_d2 */
     1465        va_arg(ap, int); /* unknown_d5 */
    14791466        maxvisiblemsglen = (guint16)va_arg(ap, int);
    14801467        va_end(ap);
     
    15171504#endif
    15181505        va_list ap;
    1519         guint16 code, rateclass;
    1520         guint32 windowsize, clear, alert, limit, disconnect, currentavg, maxavg;
     1506        guint16 code;
     1507        guint32 windowsize, clear, currentavg;
    15211508
    15221509        va_start(ap, fr);
    15231510        code = (guint16)va_arg(ap, unsigned int);
    1524         rateclass= (guint16)va_arg(ap, unsigned int);
     1511        va_arg(ap, unsigned int); /* rateclass */
    15251512        windowsize = (guint32)va_arg(ap, unsigned long);
    15261513        clear = (guint32)va_arg(ap, unsigned long);
    1527         alert = (guint32)va_arg(ap, unsigned long);
    1528         limit = (guint32)va_arg(ap, unsigned long);
    1529         disconnect = (guint32)va_arg(ap, unsigned long);
     1514        va_arg(ap, unsigned long); /* alert */
     1515        va_arg(ap, unsigned long); /* limit */
     1516        va_arg(ap, unsigned long); /* disconnect */
    15301517        currentavg = (guint32)va_arg(ap, unsigned long);
    1531         maxavg = (guint32)va_arg(ap, unsigned long);
     1518        va_arg(ap, unsigned long); /* maxavg */
    15321519        va_end(ap);
    15331520
     
    21022089                                aim_ssi_addbuddies( sess, fr->conn, OSCAR_GROUP, &list, 1, 1 );
    21032090                        }
     2091                        else if( st == 0x0A )
     2092                        {
     2093                                imcb_error( sess->aux_data, "Buddy %s is already in your list", list );
     2094                        }
    21042095                        else
    21052096                        {
     
    24132404        struct im_connection * ic = sess->aux_data;
    24142405        va_list ap;
    2415         guint16 type1, type2;
     2406        guint16 type2;
    24162407        char * sn;
    24172408
    24182409        va_start(ap, fr);
    2419         type1 = va_arg(ap, int);
     2410        va_arg(ap, int); /* type1 */
    24202411        sn = va_arg(ap, char*);
    24212412        type2 = va_arg(ap, int);
     
    25372528
    25382529        if((cur = aim_getconn_type(od->sess, AIM_CONN_TYPE_CHATNAV))) {
    2539                 int st;
    2540                
    2541                 st = aim_chatnav_createroom(od->sess, cur, room, exchange_number);
     2530                aim_chatnav_createroom(od->sess, cur, room, exchange_number);
    25422531               
    25432532                return ret;
     
    25662555        static int chat_id = 0;
    25672556        char * chatname, *s;
    2568         struct groupchat *c;
    25692557       
    25702558        chatname = g_strdup_printf("%s%s%d", isdigit(*ic->acc->user) ? "icq" : "",
     
    25752563                        *s = '0';
    25762564       
    2577         c = imcb_chat_new(ic, chatname);
    25782565        ret = oscar_chat_join_internal(ic, chatname, NULL, NULL, 4);
    25792566        aim_chat_invite(od->sess, od->conn, who, "", 4, chatname, 0x0);
     
    25812568        g_free(chatname);
    25822569       
    2583         return NULL;
     2570        return ret;
    25842571}
    25852572
  • protocols/oscar/rxqueue.c

    r87dddee r6e9ae72  
    388388         */
    389389        if (aimbs_get8(&flaphdr) != 0x2a) {
    390                 guint8 start;
    391 
    392390                aim_bstream_rewind(&flaphdr);
    393                 start = aimbs_get8(&flaphdr);
     391                aimbs_get8(&flaphdr);
    394392                imcb_error(sess->aux_data, "FLAP framing disrupted");
    395393                aim_conn_close(conn);
  • protocols/oscar/service.c

    r87dddee r6e9ae72  
    563563        groupcount = aimbs_get16(bs);
    564564        for (i = 0; i < groupcount; i++) {
    565                 guint16 group;
    566 
    567                 group = aimbs_get16(bs);
     565                aimbs_get16(bs);
    568566
    569567                imcb_error(sess->aux_data, "bifurcated migration unsupported");
     
    701699static int hostversions(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
    702700{
    703         int vercount;
    704701        guint8 *versions;
    705702
    706703        /* This is frivolous. (Thank you SmarterChild.) */
    707         vercount = aim_bstream_empty(bs)/4;
     704        aim_bstream_empty(bs); /* == vercount * 4 */
    708705        versions = aimbs_getraw(bs, aim_bstream_empty(bs));
    709706        g_free(versions);
     
    731728        aim_tlvlist_t *tl = NULL;
    732729        guint32 data;
    733         int tlvlen;
    734730        struct im_connection *ic = sess ? sess->aux_data : NULL;
    735731
     
    739735                data |= AIM_ICQ_STATE_WEBAWARE;
    740736
    741         tlvlen = aim_addtlvtochain32(&tl, 0x0006, data);
     737        aim_addtlvtochain32(&tl, 0x0006, data); /* tlvlen */
    742738
    743739        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8)))
  • protocols/purple/purple.c

    r87dddee r6e9ae72  
    181181                        /** No way to talk to the user right now, invent one when
    182182                        this becomes important.
    183                         irc_usermsg( acc->irc, "Setting with unknown type: %s (%d) Expect stuff to break..\n",
     183                        irc_rootmsg( acc->irc, "Setting with unknown type: %s (%d) Expect stuff to break..\n",
    184184                                     name, purple_account_option_get_type( o ) );
    185185                        */
     
    750750                if( bud->server_alias )
    751751                        imcb_rename_buddy( ic, bud->name, bud->server_alias );
     752                else if( bud->alias )
     753                        imcb_rename_buddy( ic, bud->name, bud->alias );
    752754               
    753755                if( group )
  • protocols/twitter/twitter.c

    r87dddee r6e9ae72  
    3030
    3131#define twitter_msg( ic, fmt... ) \
    32         do {                                                        \
    33                 struct twitter_data *td = ic->proto_data;           \
    34                 if( td->home_timeline_gc )                          \
    35                         imcb_chat_log( td->home_timeline_gc, fmt ); \
    36                 else                                                \
    37                         imcb_log( ic, fmt );                        \
     32        do {                                            \
     33                struct twitter_data *td = ic->proto_data;   \
     34                if( td->timeline_gc )                       \
     35                        imcb_chat_log( td->timeline_gc, fmt ); \
     36                else                                        \
     37                        imcb_log( ic, fmt );                    \
    3838        } while( 0 );
    3939
     
    5252
    5353        // Do stuff..
    54         twitter_get_home_timeline(ic, -1);
     54        twitter_get_timeline(ic, -1);
    5555
    5656        // If we are still logged in run this function again after timeout.
     
    6969        // Queue the main_loop
    7070        // Save the return value, so we can remove the timeout on logout.
    71         td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic);
     71        td->main_loop_id =
     72            b_timeout_add(set_getint(&ic->acc->set, "fetch_interval") * 1000, twitter_main_loop, ic);
    7273}
    7374
     
    7778{
    7879        struct twitter_data *td = ic->proto_data;
     80
     81        td->flags &= ~TWITTER_DOING_TIMELINE;
    7982
    8083        if (set_getbool(&ic->acc->set, "oauth") && !td->oauth_info)
     
    9093
    9194static const struct oauth_service twitter_oauth = {
    92         "http://api.twitter.com/oauth/request_token",
    93         "http://api.twitter.com/oauth/access_token",
     95        "https://api.twitter.com/oauth/request_token",
     96        "https://api.twitter.com/oauth/access_token",
    9497        "https://api.twitter.com/oauth/authorize",
    9598        .consumer_key = "xsDNKJuNZYkZyMcu914uEA",
     
    98101
    99102static const struct oauth_service identica_oauth = {
    100         "http://identi.ca/api/oauth/request_token",
    101         "http://identi.ca/api/oauth/access_token",
     103        "https://identi.ca/api/oauth/request_token",
     104        "https://identi.ca/api/oauth/access_token",
    102105        "https://identi.ca/api/oauth/authorize",
    103106        .consumer_key = "e147ff789fcbd8a5a07963afbb43f9da",
     
    216219                def_oauth = "true";
    217220        } else {                /* if( strcmp( acc->prpl->name, "identica" ) == 0 ) */
    218 
    219221                def_url = IDENTICA_API_URL;
    220222                def_oauth = "false";
     
    228230        s = set_add(&acc->set, "commands", "true", set_eval_bool, acc);
    229231
     232        s = set_add(&acc->set, "fetch_interval", "60", set_eval_int, acc);
     233        s->flags |= ACC_SET_OFFLINE_ONLY;
     234
     235        s = set_add(&acc->set, "fetch_mentions", "true", set_eval_bool, acc);
     236
    230237        s = set_add(&acc->set, "message_length", "140", set_eval_int, acc);
    231238
     
    235242        s = set_add(&acc->set, "show_ids", "false", set_eval_bool, acc);
    236243        s->flags |= ACC_SET_OFFLINE_ONLY;
     244
     245        s = set_add(&acc->set, "show_old_mentions", "true", set_eval_bool, acc);
    237246
    238247        s = set_add(&acc->set, "oauth", def_oauth, set_eval_bool, acc);
     
    317326        b_event_remove(td->main_loop_id);
    318327
    319         if (td->home_timeline_gc)
    320                 imcb_chat_free(td->home_timeline_gc);
     328        if (td->timeline_gc)
     329                imcb_chat_free(td->timeline_gc);
    321330
    322331        if (td) {
     
    404413        struct twitter_data *td = c->ic->proto_data;
    405414
    406         if (c != td->home_timeline_gc)
     415        if (c != td->timeline_gc)
    407416                return;         /* WTF? */
    408417
    409418        /* If the user leaves the channel: Fine. Rejoin him/her once new
    410419           tweets come in. */
    411         imcb_chat_free(td->home_timeline_gc);
    412         td->home_timeline_gc = NULL;
     420        imcb_chat_free(td->timeline_gc);
     421        td->timeline_gc = NULL;
    413422}
    414423
     
    465474                guint64 id;
    466475
    467                 if (cmd[1])
    468                         id = g_ascii_strtoull(cmd[1], NULL, 10);
    469                 else
    470                         id = td->last_status_id;
    471 
    472                 /* TODO: User feedback. */
    473                 if (id)
     476                if (cmd[1] == NULL)
     477                        twitter_status_destroy(ic, td->last_status_id);
     478                else if (sscanf(cmd[1], "%" G_GUINT64_FORMAT, &id) == 1) {
     479                        if (id < TWITTER_LOG_LENGTH && td->log)
     480                                id = td->log[id].id;
     481                       
    474482                        twitter_status_destroy(ic, id);
    475                 else
     483                } else
    476484                        twitter_msg(ic, "Could not undo last action");
    477485
     
    491499                guint64 id;
    492500
    493                 if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) &&
     501                if (g_str_has_prefix(cmd[1], "#") &&
     502                    sscanf(cmd[1] + 1, "%" G_GUINT64_FORMAT, &id) == 1) {
     503                        if (id < TWITTER_LOG_LENGTH && td->log)
     504                                id = td->log[id].id;
     505                } else if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) &&
    494506                    (tud = bu->data) && tud->last_id)
    495507                        id = tud->last_id;
    496                 else {
    497                         id = g_ascii_strtoull(cmd[1], NULL, 10);
     508                else if (sscanf(cmd[1], "%" G_GUINT64_FORMAT, &id) == 1){
    498509                        if (id < TWITTER_LOG_LENGTH && td->log)
    499510                                id = td->log[id].id;
     
    514525                guint64 id = 0;
    515526
    516                 if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) &&
     527                if (g_str_has_prefix(cmd[1], "#") &&
     528                    sscanf(cmd[1] + 1, "%" G_GUINT64_FORMAT, &id) == 1 &&
     529                    (id < TWITTER_LOG_LENGTH) && td->log) {
     530                        bu = td->log[id].bu;
     531                        if (g_slist_find(ic->bee->users, bu))
     532                                id = td->log[id].id;
     533                        else
     534                                bu = NULL;
     535                } else if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) &&
    517536                    (tud = bu->data) && tud->last_id) {
    518537                        id = tud->last_id;
     
    525544                                bu = NULL;
    526545                }
     546
    527547                if (!id || !bu) {
    528548                        twitter_msg(ic, "User `%s' does not exist or didn't "
  • protocols/twitter/twitter.h

    r87dddee r6e9ae72  
    3636{
    3737        TWITTER_HAVE_FRIENDS = 1,
     38        TWITTER_DOING_TIMELINE = 0x10000,
     39        TWITTER_GOT_TIMELINE = 0x20000,
     40        TWITTER_GOT_MENTIONS = 0x40000,
    3841} twitter_flags_t;
    3942
     
    4447        char* user;
    4548        struct oauth_info *oauth_info;
     49
     50        gpointer home_timeline_obj;
     51        gpointer mentions_obj;
     52
     53        guint64 timeline_id;
     54
    4655        GSList *follow_ids;
    4756       
    48         guint64 home_timeline_id;
    4957        guint64 last_status_id; /* For undo */
    5058        gint main_loop_id;
    51         struct groupchat *home_timeline_gc;
     59        struct groupchat *timeline_gc;
    5260        gint http_fails;
    5361        twitter_flags_t flags;
  • protocols/twitter/twitter_lib.c

    r87dddee r6e9ae72  
    7878        if (txu == NULL)
    7979                return;
     80
    8081        g_free(txu->name);
    8182        g_free(txu->screen_name);
     
    8384}
    8485
    85 
    8686/**
    8787 * Frees a twitter_xml_status struct.
     
    8989static void txs_free(struct twitter_xml_status *txs)
    9090{
     91        if (txs == NULL)
     92                return;
     93
    9194        g_free(txs->text);
    9295        txu_free(txs->user);
     
    103106        if (txl == NULL)
    104107                return;
    105         for (l = txl->list; l; l = g_slist_next(l))
    106                 if (txl->type == TXL_STATUS)
     108
     109        for (l = txl->list; l; l = g_slist_next(l)) {
     110                if (txl->type == TXL_STATUS) {
    107111                        txs_free((struct twitter_xml_status *) l->data);
    108                 else if (txl->type == TXL_ID)
     112                } else if (txl->type == TXL_ID) {
    109113                        g_free(l->data);
    110                 else if (txl->type == TXL_USER)
     114                } else if (txl->type == TXL_USER) {
    111115                        txu_free(l->data);
     116                }
     117        }
     118
    112119        g_slist_free(txl->list);
    113120        g_free(txl);
     
    115122
    116123/**
    117  * Add a buddy if it is not allready added, set the status to logged in.
     124 * Compare status elements
     125 */
     126static gint twitter_compare_elements(gconstpointer a, gconstpointer b)
     127{
     128        struct twitter_xml_status *a_status = (struct twitter_xml_status *) a;
     129        struct twitter_xml_status *b_status = (struct twitter_xml_status *) b;
     130
     131        if (a_status->created_at < b_status->created_at) {
     132                return -1;
     133        } else if (a_status->created_at > b_status->created_at) {
     134                return 1;
     135        } else {
     136                return 0;
     137        }
     138}
     139
     140/**
     141 * Add a buddy if it is not already added, set the status to logged in.
    118142 */
    119143static void twitter_add_buddy(struct im_connection *ic, char *name, const char *fullname)
     
    132156                           exact Twitter username. */
    133157                        imcb_buddy_nick_hint(ic, name, name);
    134                         imcb_chat_add_buddy(td->home_timeline_gc, name);
     158                        imcb_chat_add_buddy(td->timeline_gc, name);
    135159                } else if (g_strcasecmp(mode, "many") == 0)
    136160                        imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL);
     
    260284
    261285        /* Create the room now that we "logged in". */
    262         if (!td->home_timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)
     286        if (!td->timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)
    263287                twitter_groupchat_init(ic);
    264288
     
    436460{
    437461        struct xt_node *child, *rt = NULL;
    438         gboolean truncated = FALSE;
    439462
    440463        // Walk over the nodes children.
     
    442465                if (g_strcasecmp("text", child->name) == 0) {
    443466                        txs->text = g_memdup(child->text, child->text_len + 1);
    444                 } else if (g_strcasecmp("truncated", child->name) == 0 && child->text) {
    445                         truncated = bool2int(child->text);
    446467                } else if (g_strcasecmp("retweeted_status", child->name) == 0) {
    447468                        rt = child;
     
    464485        }
    465486
    466         /* If it's a truncated retweet, get the original because dots suck. */
    467         if (truncated && rt) {
     487        /* If it's a (truncated) retweet, get the original. Even if the API claims it
     488           wasn't truncated because it may be lying. */
     489        if (rt) {
    468490                struct twitter_xml_status *rtxs = g_new0(struct twitter_xml_status, 1);
    469491                if (twitter_xt_get_status(rt, rtxs) != XT_HANDLED) {
     
    475497                txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text);
    476498                txs_free(rtxs);
     499        } else {
     500                struct xt_node *urls, *url;
     501               
     502                urls = xt_find_path(node, "entities/urls");
     503                for (url = urls ? urls->children : NULL; url; url = url->next) {
     504                        /* "short" is a reserved word. :-P */
     505                        struct xt_node *kort = xt_find_node(url->children, "url");
     506                        struct xt_node *disp = xt_find_node(url->children, "display_url");
     507                        char *pos, *new;
     508                       
     509                        if (!kort || !kort->text || !disp || !disp->text ||
     510                            !(pos = strstr(txs->text, kort->text)))
     511                                continue;
     512                       
     513                        *pos = '\0';
     514                        new = g_strdup_printf("%s%s &lt;%s&gt;%s", txs->text, kort->text,
     515                                              disp->text, pos + strlen(kort->text));
     516                       
     517                        g_free(txs->text);
     518                        txs->text = new;
     519                }
    477520        }
    478521
     
    520563
    521564        return XT_HANDLED;
    522 }
    523 
    524 static void twitter_http_get_home_timeline(struct http_request *req);
    525 
    526 /**
    527  * Get the timeline.
    528  */
    529 void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor)
    530 {
    531         struct twitter_data *td = ic->proto_data;
    532 
    533         char *args[4];
    534         args[0] = "cursor";
    535         args[1] = g_strdup_printf("%lld", (long long) next_cursor);
    536         if (td->home_timeline_id) {
    537                 args[2] = "since_id";
    538                 args[3] = g_strdup_printf("%llu", (long long unsigned int) td->home_timeline_id);
    539         }
    540 
    541         twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args,
    542                      td->home_timeline_id ? 4 : 2);
    543 
    544         g_free(args[1]);
    545         if (td->home_timeline_id) {
    546                 g_free(args[3]);
    547         }
    548565}
    549566
     
    586603        GSList *l;
    587604
    588         td->home_timeline_gc = gc = imcb_chat_new(ic, "home/timeline");
     605        td->timeline_gc = gc = imcb_chat_new(ic, "twitter/timeline");
    589606
    590607        name_hint = g_strdup_printf("%s_%s", td->prefix, ic->acc->user);
     
    595612                bee_user_t *bu = l->data;
    596613                if (bu->ic == ic)
    597                         imcb_chat_add_buddy(td->home_timeline_gc, bu->handle);
     614                        imcb_chat_add_buddy(td->timeline_gc, bu->handle);
    598615        }
    599616}
     
    608625        struct twitter_xml_status *status;
    609626        struct groupchat *gc;
     627        guint64 last_id = 0;
    610628
    611629        // Create a new groupchat if it does not exsist.
    612         if (!td->home_timeline_gc)
     630        if (!td->timeline_gc)
    613631                twitter_groupchat_init(ic);
    614632
    615         gc = td->home_timeline_gc;
     633        gc = td->timeline_gc;
    616634        if (!gc->joined)
    617635                imcb_chat_add_buddy(gc, ic->acc->user);
     
    621639
    622640                status = l->data;
    623                 if (status->user == NULL || status->text == NULL)
     641                if (status->user == NULL || status->text == NULL || last_id == status->id)
    624642                        continue;
    625643
    626                 twitter_add_buddy(ic, status->user->screen_name, status->user->name);
     644                last_id = status->id;
    627645
    628646                strip_html(status->text);
     647
    629648                msg = twitter_msg_add_id(ic, status, "");
    630649
    631650                // Say it!
    632                 if (g_strcasecmp(td->user, status->user->screen_name) == 0)
     651                if (g_strcasecmp(td->user, status->user->screen_name) == 0) {
    633652                        imcb_chat_log(gc, "You: %s", msg ? msg : status->text);
    634                 else
     653                } else {
     654                        twitter_add_buddy(ic, status->user->screen_name, status->user->name);
     655
    635656                        imcb_chat_msg(gc, status->user->screen_name,
    636657                                      msg ? msg : status->text, 0, status->created_at);
     658                }
    637659
    638660                g_free(msg);
    639661
    640                 // Update the home_timeline_id to hold the highest id, so that by the next request
     662                // Update the timeline_id to hold the highest id, so that by the next request
    641663                // we won't pick up the updates already in the list.
    642                 td->home_timeline_id = MAX(td->home_timeline_id, status->id);
     664                td->timeline_id = MAX(td->timeline_id, status->id);
    643665        }
    644666}
     
    654676        char from[MAX_STRING];
    655677        gboolean mode_one;
     678        guint64 last_id = 0;
    656679
    657680        mode_one = g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "one") == 0;
     
    666689
    667690                status = l->data;
     691                if (status->user == NULL || status->text == NULL || last_id == status->id)
     692                        continue;
     693
     694                last_id = status->id;
    668695
    669696                strip_html(status->text);
     
    680707                               text ? text : status->text, 0, status->created_at);
    681708
    682                 // Update the home_timeline_id to hold the highest id, so that by the next request
     709                // Update the timeline_id to hold the highest id, so that by the next request
    683710                // we won't pick up the updates already in the list.
    684                 td->home_timeline_id = MAX(td->home_timeline_id, status->id);
     711                td->timeline_id = MAX(td->timeline_id, status->id);
    685712
    686713                g_free(text);
    687714                g_free(prefix);
     715        }
     716}
     717
     718static void twitter_http_get_home_timeline(struct http_request *req);
     719static void twitter_http_get_mentions(struct http_request *req);
     720
     721/**
     722 * Get the timeline with optionally mentions
     723 */
     724void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor)
     725{
     726        struct twitter_data *td = ic->proto_data;
     727        gboolean include_mentions = set_getbool(&ic->acc->set, "fetch_mentions");
     728
     729        if (td->flags & TWITTER_DOING_TIMELINE) {
     730                return;
     731        }
     732
     733        td->flags |= TWITTER_DOING_TIMELINE;
     734
     735        twitter_get_home_timeline(ic, next_cursor);
     736
     737        if (include_mentions) {
     738                twitter_get_mentions(ic, next_cursor);
     739        }
     740}
     741
     742/**
     743 * Call this one after receiving timeline/mentions. Show to user once we have
     744 * both.
     745 */
     746void twitter_flush_timeline(struct im_connection *ic)
     747{
     748        struct twitter_data *td = ic->proto_data;
     749        gboolean include_mentions = set_getbool(&ic->acc->set, "fetch_mentions");
     750        gboolean show_old_mentions = set_getbool(&ic->acc->set, "show_old_mentions");
     751        struct twitter_xml_list *home_timeline = td->home_timeline_obj;
     752        struct twitter_xml_list *mentions = td->mentions_obj;
     753        GSList *output = NULL;
     754        GSList *l;
     755
     756        if (!(td->flags & TWITTER_GOT_TIMELINE)) {
     757                return;
     758        }
     759
     760        if (include_mentions && !(td->flags & TWITTER_GOT_MENTIONS)) {
     761                return;
     762        }
     763
     764        if (home_timeline && home_timeline->list) {
     765                for (l = home_timeline->list; l; l = g_slist_next(l)) {
     766                        output = g_slist_insert_sorted(output, l->data, twitter_compare_elements);
     767                }
     768        }
     769
     770        if (include_mentions && mentions && mentions->list) {
     771                for (l = mentions->list; l; l = g_slist_next(l)) {
     772                        if (!show_old_mentions && output && twitter_compare_elements(l->data, output->data) < 0) {
     773                                continue;
     774                        }
     775
     776                        output = g_slist_insert_sorted(output, l->data, twitter_compare_elements);
     777                }
     778        }
     779
     780        // See if the user wants to see the messages in a groupchat window or as private messages.
     781        if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)
     782                twitter_groupchat(ic, output);
     783        else
     784                twitter_private_message_chat(ic, output);
     785
     786        g_slist_free(output);
     787
     788        if (home_timeline && home_timeline->list) {
     789                txl_free(home_timeline);
     790        }
     791
     792        if (mentions && mentions->list) {
     793                txl_free(mentions);
     794        }
     795
     796        td->flags &= ~(TWITTER_DOING_TIMELINE | TWITTER_GOT_TIMELINE | TWITTER_GOT_MENTIONS);
     797}
     798
     799/**
     800 * Get the timeline.
     801 */
     802void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor)
     803{
     804        struct twitter_data *td = ic->proto_data;
     805
     806        td->home_timeline_obj = NULL;
     807        td->flags &= ~TWITTER_GOT_TIMELINE;
     808
     809        char *args[6];
     810        args[0] = "cursor";
     811        args[1] = g_strdup_printf("%lld", (long long) next_cursor);
     812        args[2] = "include_entities";
     813        args[3] = "true";
     814        if (td->timeline_id) {
     815                args[4] = "since_id";
     816                args[5] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id);
     817        }
     818
     819        if (twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args,
     820                     td->timeline_id ? 6 : 4) == NULL) {
     821                if (++td->http_fails >= 5)
     822                        imcb_error(ic, "Could not retrieve %s: %s",
     823                                   TWITTER_HOME_TIMELINE_URL, "connection failed");
     824                td->flags |= TWITTER_GOT_TIMELINE;
     825                twitter_flush_timeline(ic);
     826        }
     827
     828        g_free(args[1]);
     829        if (td->timeline_id) {
     830                g_free(args[5]);
     831        }
     832}
     833
     834/**
     835 * Get mentions.
     836 */
     837void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor)
     838{
     839        struct twitter_data *td = ic->proto_data;
     840
     841        td->mentions_obj = NULL;
     842        td->flags &= ~TWITTER_GOT_MENTIONS;
     843
     844        char *args[6];
     845        args[0] = "cursor";
     846        args[1] = g_strdup_printf("%lld", (long long) next_cursor);
     847        args[2] = "include_entities";
     848        args[3] = "true";
     849        if (td->timeline_id) {
     850                args[4] = "since_id";
     851                args[5] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id);
     852        }
     853
     854        if (twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions, ic, 0, args,
     855                     td->timeline_id ? 6 : 4) == NULL) {
     856                if (++td->http_fails >= 5)
     857                        imcb_error(ic, "Could not retrieve %s: %s",
     858                                   TWITTER_MENTIONS_URL, "connection failed");
     859                td->flags |= TWITTER_GOT_MENTIONS;
     860                twitter_flush_timeline(ic);
     861        }
     862
     863        g_free(args[1]);
     864        if (td->timeline_id) {
     865                g_free(args[5]);
    688866        }
    689867}
     
    713891                imcb_error(ic, "Authentication failure");
    714892                imc_logout(ic, FALSE);
    715                 return;
     893                goto end;
    716894        } else {
    717895                // It didn't go well, output the error and return.
     
    720898                                   TWITTER_HOME_TIMELINE_URL, twitter_parse_error(req));
    721899
    722                 return;
     900                goto end;
    723901        }
    724902
     
    733911        xt_free(parser);
    734912
    735         // See if the user wants to see the messages in a groupchat window or as private messages.
    736         if (txl->list == NULL);
    737         else if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)
    738                 twitter_groupchat(ic, txl->list);
    739         else
    740                 twitter_private_message_chat(ic, txl->list);
    741 
    742         // Free the structure. 
    743         txl_free(txl);
     913        td->home_timeline_obj = txl;
     914
     915      end:
     916        td->flags |= TWITTER_GOT_TIMELINE;
     917
     918        twitter_flush_timeline(ic);
     919}
     920
     921/**
     922 * Callback for getting mentions.
     923 */
     924static void twitter_http_get_mentions(struct http_request *req)
     925{
     926        struct im_connection *ic = req->data;
     927        struct twitter_data *td;
     928        struct xt_parser *parser;
     929        struct twitter_xml_list *txl;
     930
     931        // Check if the connection is still active.
     932        if (!g_slist_find(twitter_connections, ic))
     933                return;
     934
     935        td = ic->proto_data;
     936
     937        // Check if the HTTP request went well.
     938        if (req->status_code == 200) {
     939                td->http_fails = 0;
     940                if (!(ic->flags & OPT_LOGGED_IN))
     941                        imcb_connected(ic);
     942        } else if (req->status_code == 401) {
     943                imcb_error(ic, "Authentication failure");
     944                imc_logout(ic, FALSE);
     945                goto end;
     946        } else {
     947                // It didn't go well, output the error and return.
     948                if (++td->http_fails >= 5)
     949                        imcb_error(ic, "Could not retrieve %s: %s",
     950                                   TWITTER_MENTIONS_URL, twitter_parse_error(req));
     951
     952                goto end;
     953        }
     954
     955        txl = g_new0(struct twitter_xml_list, 1);
     956        txl->list = NULL;
     957
     958        // Parse the data.
     959        parser = xt_new(NULL, txl);
     960        xt_feed(parser, req->reply_body, req->body_size);
     961        // The root <statuses> node should hold the list of statuses <status>
     962        twitter_xt_get_status_list(ic, parser->root, txl);
     963        xt_free(parser);
     964
     965        td->mentions_obj = txl;
     966
     967      end:
     968        td->flags |= TWITTER_GOT_MENTIONS;
     969
     970        twitter_flush_timeline(ic);
    744971}
    745972
  • protocols/twitter/twitter_lib.h

    r87dddee r6e9ae72  
    7676#define TWITTER_BLOCKS_DESTROY_URL "/blocks/destroy/"
    7777
     78void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor);
    7879void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor);
    7980void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor);
     81void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor);
    8082void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor);
    8183
  • protocols/yahoo/libyahoo2.c

    r87dddee r6e9ae72  
    18091809        struct yahoo_input_data *yid = had->yid;
    18101810        struct yahoo_data *yd = yid->yd;
    1811         struct http_request *req;
    18121811        char *login, *passwd, *chal;
    18131812        char *url;
     
    18231822                               (int) time(NULL), login, passwd, chal);
    18241823       
    1825         req = http_dorequest_url(url, yahoo_https_auth_token_finish, had);
     1824        http_dorequest_url(url, yahoo_https_auth_token_finish, had);
    18261825       
    18271826        g_free(url);
     
    18701869static void yahoo_https_auth_init(struct yahoo_https_auth_data *had)
    18711870{
    1872         struct http_request *req;
    18731871        char *url;
    18741872       
     
    18761874                              (int) time(NULL), had->token);
    18771875       
    1878         req = http_dorequest_url(url, yahoo_https_auth_finish, had);
     1876        http_dorequest_url(url, yahoo_https_auth_finish, had);
    18791877       
    18801878        g_free(url);
     
    19901988{
    19911989        struct yahoo_data *yd = yid->yd;
    1992         char *login_id;
    1993         char *handle;
    19941990        char *url = NULL;
    19951991        int login_status = -1;
     
    20001996                struct yahoo_pair *pair = l->data;
    20011997                if (pair->key == 0)
    2002                         login_id = pair->value;
     1998                        ; /* login_id */
    20031999                else if (pair->key == 1)
    2004                         handle = pair->value;
     2000                        ; /* handle */
    20052001                else if (pair->key == 20)
    20062002                        url = pair->value;
     
    20892085        char *msg = NULL;
    20902086        char *name = NULL;
    2091         long tm = 0L;
    20922087        int state = YAHOO_STATUS_AVAILABLE;
    2093         int online = 0;
    20942088        int away = 0;
    20952089        int idle = 0;
     
    21112105                        state = strtol(pair->value, NULL, 10);
    21122106                else if (pair->key == 15)
    2113                         tm = strtol(pair->value, NULL, 10);
     2107                        ; /* tm */
    21142108                else if (pair->key == 13)
    2115                         online = strtol(pair->value, NULL, 10);
     2109                        ; /* online */
    21162110                else if (pair->key == 47)
    21172111                        away = strtol(pair->value, NULL, 10);
     
    21402134        char *where = NULL;
    21412135        int status = 0;
    2142         char *me = NULL;
    21432136
    21442137        struct yahoo_buddy *bud = NULL;
     
    21482141                struct yahoo_pair *pair = l->data;
    21492142                if (pair->key == 1)
    2150                         me = pair->value;
     2143                        ; /* Me... don't care */
    21512144                if (pair->key == 7)
    21522145                        who = pair->value;
     
    22042197        char *who = NULL;
    22052198        char *where = NULL;
    2206         int unk_66 = 0;
    2207         char *me = NULL;
    22082199        struct yahoo_buddy *bud;
    22092200
     
    22142205                struct yahoo_pair *pair = l->data;
    22152206                if (pair->key == 1)
    2216                         me = pair->value;
     2207                        ; /* Me... don't care */
    22172208                else if (pair->key == 7)
    22182209                        who = pair->value;
     
    22202211                        where = pair->value;
    22212212                else if (pair->key == 66)
    2222                         unk_66 = strtol(pair->value, NULL, 10);
     2213                        ; /* unk_66 */
    22232214                else
    22242215                        DEBUG_MSG(("unknown key: %d = %s", pair->key,
     
    22562247        struct yahoo_packet *pkt)
    22572248{
    2258         char *who = NULL;
    2259         int status = 0;
    2260         char *me = NULL;
    2261         int un_ignore = 0;
    2262 
    22632249        YList *l;
    22642250        for (l = pkt->hash; l; l = l->next) {
    22652251                struct yahoo_pair *pair = l->data;
    22662252                if (pair->key == 0)
    2267                         who = pair->value;
     2253                        ; /* who */
    22682254                if (pair->key == 1)
    2269                         me = pair->value;
     2255                        ; /* Me... don't care */
    22702256                if (pair->key == 13)    /* 1 == ignore, 2 == unignore */
    2271                         un_ignore = strtol(pair->value, NULL, 10);
     2257                        ;
    22722258                if (pair->key == 66)
    2273                         status = strtol(pair->value, NULL, 10);
     2259                        ; /* status */
    22742260        }
    22752261
     
    22932279        char *me = NULL;
    22942280        char *room = NULL;
    2295         char *voice_room = NULL;
    22962281
    22972282        YList *l;
     
    23032288                        me = pair->value;
    23042289                if (pair->key == 13)
    2305                         voice_room = pair->value;
     2290                        ; /* voice room */
    23062291                if (pair->key == 57)
    23072292                        room = pair->value;
     
    24382423        struct yahoo_packet *pkt)
    24392424{
    2440         char *me = NULL;
    24412425        char *key = NULL;
    24422426        char *who = NULL;
     
    24472431                struct yahoo_pair *pair = l->data;
    24482432                if (pair->key == 5)
    2449                         me = pair->value;
     2433                        ; /* me */
    24502434                if (pair->key == 61)
    24512435                        key = pair->value;
     
    33693353        struct yahoo_webcam *wcm = y->wcm;
    33703354        struct yahoo_input_data *yid;
    3371         struct yahoo_server_settings *yss;
    33723355
    33733356        if (!wcm || !wcm->server || !wcm->key)
     
    33813364        yid->wcm = y->wcm;
    33823365        y->wcm = NULL;
    3383 
    3384         yss = y->yd->server_settings;
    33853366
    33863367        yid->wcd = y_new0(struct yahoo_webcam_data, 1);
     
    49754956        YList *l;
    49764957        struct send_file_data *sfd;
    4977         char *who = NULL;
    4978         char *filename = NULL;
    49794958        char *id = NULL;
    49804959        char *token = NULL;
     
    49844963                switch (pair->key) {
    49854964                case 4:
    4986                         who = pair->value;
     4965                        /* who */
    49874966                        break;
    49884967                case 5:
     
    49984977                        break;
    49994978                case 27:
    5000                         filename = pair->value;
     4979                        /* filename */
    50014980                        break;
    50024981                }
     
    50235002{
    50245003        YList *l;
    5025         char *who = NULL;
    5026         char *filename = NULL;
    50275004        char *id = NULL;
    50285005        char *token = NULL;
     
    50365013                case 1:
    50375014                case 4:
    5038                         who = pair->value;
     5015                        /* who */
    50395016                        break;
    50405017                case 5:
     
    50535030                        break;
    50545031                case 27:
    5055                         filename = pair->value;
     5032                        /* filename */
    50565033                        break;
    50575034                }
  • query.c

    r87dddee r6e9ae72  
    150150                        imcb_log( q->ic, "Accepted: %s", q->question );
    151151                else
    152                         irc_usermsg( irc, "Accepted: %s", q->question );
     152                        irc_rootmsg( irc, "Accepted: %s", q->question );
    153153                if( q->yes )
    154154                        q->yes( q->data );
     
    159159                        imcb_log( q->ic, "Rejected: %s", q->question );
    160160                else
    161                         irc_usermsg( irc, "Rejected: %s", q->question );
     161                        irc_rootmsg( irc, "Rejected: %s", q->question );
    162162                if( q->no )
    163163                        q->no( q->data );
     
    179179        else
    180180        {
    181                 irc_usermsg( irc, "New request: %s\nYou can use the \2yes\2/\2no\2 commands to accept/reject this request.", q->question );
     181                irc_rootmsg( irc, "New request: %s\nYou can use the \2yes\2/\2no\2 commands to accept/reject this request.", q->question );
    182182        }
    183183}
  • root_commands.c

    r87dddee r6e9ae72  
    4242                        if( cmd[blaat] == NULL )                               \
    4343                        {                                                      \
    44                                 irc_usermsg( irc, "Not enough parameters given (need %d).", x ); \
     44                                irc_rootmsg( irc, "Not enough parameters given (need %d).", x ); \
    4545                                return y;                                      \
    4646                        }                                                      \
     
    6969                }
    7070       
    71         irc_usermsg( irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[0] );
     71        irc_rootmsg( irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[0] );
    7272}
    7373
     
    9090        if( s )
    9191        {
    92                 irc_usermsg( irc, "%s", s );
     92                irc_rootmsg( irc, "%s", s );
    9393                g_free( s );
    9494        }
    9595        else
    9696        {
    97                 irc_usermsg( irc, "Error opening helpfile." );
     97                irc_rootmsg( irc, "Error opening helpfile." );
    9898        }
    9999}
     
    110110        if( irc->status & USTATUS_IDENTIFIED )
    111111        {
    112                 irc_usermsg( irc, "You're already logged in." );
     112                irc_rootmsg( irc, "You're already logged in." );
    113113                return;
    114114        }
     
    128128        else if( irc->b->accounts != NULL )
    129129        {
    130                 irc_usermsg( irc,
     130                irc_rootmsg( irc,
    131131                             "You're trying to identify yourself, but already have "
    132132                             "at least one IM account set up. "
     
    138138        if( password == NULL )
    139139        {
    140                 irc_usermsg( irc, "About to identify, use /OPER to enter the password" );
     140                irc_rootmsg( irc, "About to identify, use /OPER to enter the password" );
    141141                irc->status |= OPER_HACK_IDENTIFY;
    142142                return;
     
    150150        switch (status) {
    151151        case STORAGE_INVALID_PASSWORD:
    152                 irc_usermsg( irc, "Incorrect password" );
     152                irc_rootmsg( irc, "Incorrect password" );
    153153                break;
    154154        case STORAGE_NO_SUCH_USER:
    155                 irc_usermsg( irc, "The nick is (probably) not registered" );
     155                irc_rootmsg( irc, "The nick is (probably) not registered" );
    156156                break;
    157157        case STORAGE_OK:
    158                 irc_usermsg( irc, "Password accepted%s",
     158                irc_rootmsg( irc, "Password accepted%s",
    159159                             load ? ", settings and accounts loaded" : "" );
    160160                irc_setpass( irc, password );
     
    192192        case STORAGE_OTHER_ERROR:
    193193        default:
    194                 irc_usermsg( irc, "Unknown error while loading configuration" );
     194                irc_rootmsg( irc, "Unknown error while loading configuration" );
    195195                break;
    196196        }
     
    215215        if( global.conf->authmode == AUTHMODE_REGISTERED )
    216216        {
    217                 irc_usermsg( irc, "This server does not allow registering new accounts" );
     217                irc_rootmsg( irc, "This server does not allow registering new accounts" );
    218218                return;
    219219        }
     
    221221        if( cmd[1] == NULL )
    222222        {
    223                 irc_usermsg( irc, "About to register, use /OPER to enter the password" );
     223                irc_rootmsg( irc, "About to register, use /OPER to enter the password" );
    224224                irc->status |= OPER_HACK_REGISTER;
    225225                return;
     
    228228        switch( storage_save( irc, cmd[1], FALSE ) ) {
    229229                case STORAGE_ALREADY_EXISTS:
    230                         irc_usermsg( irc, "Nick is already registered" );
     230                        irc_rootmsg( irc, "Nick is already registered" );
    231231                        break;
    232232                       
    233233                case STORAGE_OK:
    234                         irc_usermsg( irc, "Account successfully created" );
     234                        irc_rootmsg( irc, "Account successfully created" );
    235235                        irc_setpass( irc, cmd[1] );
    236236                        irc->status |= USTATUS_IDENTIFIED;
     
    245245
    246246                default:
    247                         irc_usermsg( irc, "Error registering" );
     247                        irc_rootmsg( irc, "Error registering" );
    248248                        break;
    249249        }
     
    257257        switch (status) {
    258258        case STORAGE_NO_SUCH_USER:
    259                 irc_usermsg( irc, "That account does not exist" );
     259                irc_rootmsg( irc, "That account does not exist" );
    260260                break;
    261261        case STORAGE_INVALID_PASSWORD:
    262                 irc_usermsg( irc, "Password invalid" );
     262                irc_rootmsg( irc, "Password invalid" );
    263263                break;
    264264        case STORAGE_OK:
     
    266266                irc->status &= ~USTATUS_IDENTIFIED;
    267267                irc_umode_set( irc, "-R", 1 );
    268                 irc_usermsg( irc, "Account `%s' removed", irc->user->nick );
     268                irc_rootmsg( irc, "Account `%s' removed", irc->user->nick );
    269269                break;
    270270        default:
    271                 irc_usermsg( irc, "Error: `%d'", status );
     271                irc_rootmsg( irc, "Error: `%d'", status );
    272272                break;
    273273        }
     
    277277{
    278278        if( ( irc->status & USTATUS_IDENTIFIED ) == 0 )
    279                 irc_usermsg( irc, "Please create an account first" );
     279                irc_rootmsg( irc, "Please create an account first" );
    280280        else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK )
    281                 irc_usermsg( irc, "Configuration saved" );
    282         else
    283                 irc_usermsg( irc, "Configuration could not be saved!" );
     281                irc_rootmsg( irc, "Configuration saved" );
     282        else
     283                irc_rootmsg( irc, "Configuration could not be saved!" );
    284284}
    285285
     
    290290       
    291291        if( ( val = set_getstr( head, key ) ) )
    292                 irc_usermsg( irc, "%s = `%s'", key, val );
     292                irc_rootmsg( irc, "%s = `%s'", key, val );
    293293        else if( !( set = set_find( head, key ) ) )
    294294        {
    295                 irc_usermsg( irc, "Setting `%s' does not exist.", key );
     295                irc_rootmsg( irc, "Setting `%s' does not exist.", key );
    296296                if( *head == irc->b->set )
    297                         irc_usermsg( irc, "It might be an account or channel setting. "
     297                        irc_rootmsg( irc, "It might be an account or channel setting. "
    298298                                     "See \x02help account set\x02 and \x02help channel set\x02." );
    299299        }
    300300        else if( set->flags & SET_PASSWORD )
    301                 irc_usermsg( irc, "%s = `********' (hidden)", key );
    302         else
    303                 irc_usermsg( irc, "%s is empty", key );
     301                irc_rootmsg( irc, "%s = `********' (hidden)", key );
     302        else
     303                irc_rootmsg( irc, "%s is empty", key );
    304304}
    305305
     
    344344                           feedback. */
    345345                        if( st )
    346                                 irc_usermsg( irc, "Setting changed successfully" );
     346                                irc_rootmsg( irc, "Setting changed successfully" );
    347347                        else
    348                                 irc_usermsg( irc, "Failed to change setting" );
     348                                irc_rootmsg( irc, "Failed to change setting" );
    349349                }
    350350                else
     
    362362                while( s )
    363363                {
    364                         if( !( s->flags & SET_HIDDEN ) )
     364                        if( set_isvisible( s ) )
    365365                                cmd_showset( irc, &s, s->key );
    366366                        s = s->next;
     
    377377        if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY )
    378378        {
    379                 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" );
     379                irc_rootmsg( irc, "This setting can only be changed when the account is %s-line", "off" );
    380380                return 0;
    381381        }
    382382        else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY )
    383383        {
    384                 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" );
     384                irc_rootmsg( irc, "This setting can only be changed when the account is %s-line", "on" );
    385385                return 0;
    386386        }
     
    396396        if( global.conf->authmode == AUTHMODE_REGISTERED && !( irc->status & USTATUS_IDENTIFIED ) )
    397397        {
    398                 irc_usermsg( irc, "This server only accepts registered users" );
     398                irc_rootmsg( irc, "This server only accepts registered users" );
    399399                return;
    400400        }
     
    413413                                if( strcmp( a->pass, PASSWORD_PENDING ) == 0 )
    414414                                {
    415                                         irc_usermsg( irc, "Enter password for account %s(%s) "
    416                                                      "first (use /OPER)", a->prpl->name, a->user );
     415                                        irc_rootmsg( irc, "Enter password for account %s "
     416                                                     "first (use /OPER)", a->tag );
    417417                                        return;
    418418                                }
     
    425425                if( prpl == NULL )
    426426                {
    427                         irc_usermsg( irc, "Unknown protocol" );
     427                        irc_rootmsg( irc, "Unknown protocol" );
    428428                        return;
    429429                }
     
    431431                for( a = irc->b->accounts; a; a = a->next )
    432432                        if( a->prpl == prpl && prpl->handle_cmp( a->user, cmd[3] ) == 0 )
    433                                 irc_usermsg( irc, "Warning: You already have an account with "
     433                                irc_rootmsg( irc, "Warning: You already have an account with "
    434434                                             "protocol `%s' and username `%s'. Are you accidentally "
    435435                                             "trying to add it twice?", prpl->name, cmd[3] );
     
    438438                if( cmd[5] )
    439439                {
    440                         irc_usermsg( irc, "Warning: Passing a servername/other flags to `account add' "
     440                        irc_rootmsg( irc, "Warning: Passing a servername/other flags to `account add' "
    441441                                          "is now deprecated. Use `account set' instead." );
    442442                        set_setstr( &a->set, "server", cmd[5] );
    443443                }
    444444               
    445                 irc_usermsg( irc, "Account successfully added%s", cmd[4] ? "" :
     445                irc_rootmsg( irc, "Account successfully added with tag %s%s",
     446                             a->tag, cmd[4] ? "" :
    446447                             ", now use /OPER to enter the password" );
    447448               
     
    453454               
    454455                if( strchr( irc->umode, 'b' ) )
    455                         irc_usermsg( irc, "Account list:" );
     456                        irc_rootmsg( irc, "Account list:" );
    456457               
    457458                for( a = irc->b->accounts; a; a = a->next )
     
    468469                                con = "";
    469470                       
    470                         irc_usermsg( irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con );
     471                        irc_rootmsg( irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con );
    471472                       
    472473                        i ++;
    473474                }
    474                 irc_usermsg( irc, "End of account list" );
     475                irc_rootmsg( irc, "End of account list" );
    475476               
    476477                return;
     
    484485                if ( irc->b->accounts )
    485486                {
    486                         irc_usermsg( irc, "Trying to get all accounts connected..." );
     487                        irc_rootmsg( irc, "Trying to get all accounts connected..." );
    487488               
    488489                        for( a = irc->b->accounts; a; a = a->next )
     
    490491                                {
    491492                                        if( strcmp( a->pass, PASSWORD_PENDING ) == 0 )
    492                                                 irc_usermsg( irc, "Enter password for account %s(%s) "
    493                                                              "first (use /OPER)", a->prpl->name, a->user );
     493                                                irc_rootmsg( irc, "Enter password for account %s "
     494                                                             "first (use /OPER)", a->tag );
    494495                                        else
    495496                                                account_on( irc->b, a );
     
    498499                else
    499500                {
    500                         irc_usermsg( irc, "No accounts known. Use `account add' to add one." );
     501                        irc_rootmsg( irc, "No accounts known. Use `account add' to add one." );
    501502                }
    502503               
     
    505506        else if( len >= 2 && g_strncasecmp( cmd[1], "off", len ) == 0 )
    506507        {
    507                 irc_usermsg( irc, "Deactivating all active (re)connections..." );
     508                irc_rootmsg( irc, "Deactivating all active (re)connections..." );
    508509               
    509510                for( a = irc->b->accounts; a; a = a->next )
     
    530531            ( a = account_get( irc->b, cmd[1] ) ) == NULL )
    531532        {
    532                 irc_usermsg( irc, "Could not find account `%s'. Note that the syntax "
     533                irc_rootmsg( irc, "Could not find account `%s'. Note that the syntax "
    533534                             "of the account command changed, see \x02help account\x02.", cmd[1] );
    534535               
     
    540541                if( a->ic )
    541542                {
    542                         irc_usermsg( irc, "Account is still logged in, can't delete" );
     543                        irc_rootmsg( irc, "Account is still logged in, can't delete" );
    543544                }
    544545                else
    545546                {
    546547                        account_del( irc->b, a );
    547                         irc_usermsg( irc, "Account deleted" );
     548                        irc_rootmsg( irc, "Account deleted" );
    548549                }
    549550        }
     
    551552        {
    552553                if( a->ic )
    553                         irc_usermsg( irc, "Account already online" );
     554                        irc_rootmsg( irc, "Account already online" );
    554555                else if( strcmp( a->pass, PASSWORD_PENDING ) == 0 )
    555                         irc_usermsg( irc, "Enter password for account %s(%s) "
    556                                      "first (use /OPER)", a->prpl->name, a->user );
     556                        irc_rootmsg( irc, "Enter password for account %s "
     557                                     "first (use /OPER)", a->tag );
    557558                else
    558559                        account_on( irc->b, a );
     
    567568                {
    568569                        cancel_auto_reconnect( a );
    569                         irc_usermsg( irc, "Reconnect cancelled" );
    570                 }
    571                 else
    572                 {
    573                         irc_usermsg( irc, "Account already offline" );
     570                        irc_rootmsg( irc, "Reconnect cancelled" );
     571                }
     572                else
     573                {
     574                        irc_rootmsg( irc, "Account already offline" );
    574575                }
    575576        }
     
    580581        else
    581582        {
    582                 irc_usermsg( irc, "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[2] );
     583                irc_rootmsg( irc, "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[2] );
    583584        }
    584585}
     
    597598               
    598599                if( strchr( irc->umode, 'b' ) )
    599                         irc_usermsg( irc, "Channel list:" );
     600                        irc_rootmsg( irc, "Channel list:" );
    600601               
    601602                for( l = irc->channels; l; l = l->next )
     
    603604                        irc_channel_t *ic = l->data;
    604605                       
    605                         irc_usermsg( irc, "%2d. %s, %s channel%s", i, ic->name,
     606                        irc_rootmsg( irc, "%2d. %s, %s channel%s", i, ic->name,
    606607                                     set_getstr( &ic->set, "type" ),
    607608                                     ic->flags & IRC_CHANNEL_JOINED ? " (joined)" : "" );
     
    609610                        i ++;
    610611                }
    611                 irc_usermsg( irc, "End of channel list" );
     612                irc_rootmsg( irc, "End of channel list" );
    612613               
    613614                return;
     
    623624                        cmd_set_real( irc, cmd + 1, &ic->set, NULL );
    624625                else
    625                         irc_usermsg( irc, "Could not find channel `%s'", cmd[1] );
     626                        irc_rootmsg( irc, "Could not find channel `%s'", cmd[1] );
    626627               
    627628                return;
     
    640641                    ic != ic->irc->default_channel )
    641642                {
    642                         irc_usermsg( irc, "Channel %s deleted.", ic->name );
     643                        irc_rootmsg( irc, "Channel %s deleted.", ic->name );
    643644                        irc_channel_free( ic );
    644645                }
    645646                else
    646                         irc_usermsg( irc, "Couldn't remove channel (main channel %s or "
     647                        irc_rootmsg( irc, "Couldn't remove channel (main channel %s or "
    647648                                          "channels you're still in cannot be deleted).",
    648649                                          irc->default_channel->name );
     
    650651        else
    651652        {
    652                 irc_usermsg( irc, "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "channel", cmd[1] );
     653                irc_rootmsg( irc, "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "channel", cmd[1] );
    653654        }
    654655}
     
    668669        if( !( a = account_get( irc->b, cmd[1] ) ) )
    669670        {
    670                 irc_usermsg( irc, "Invalid account" );
     671                irc_rootmsg( irc, "Invalid account" );
    671672                return;
    672673        }
    673674        else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
    674675        {
    675                 irc_usermsg( irc, "That account is not on-line" );
     676                irc_rootmsg( irc, "That account is not on-line" );
    676677                return;
    677678        }
     
    681682                if( !nick_ok( cmd[3] ) )
    682683                {
    683                         irc_usermsg( irc, "The requested nick `%s' is invalid", cmd[3] );
     684                        irc_rootmsg( irc, "The requested nick `%s' is invalid", cmd[3] );
    684685                        return;
    685686                }
    686687                else if( irc_user_by_name( irc, cmd[3] ) )
    687688                {
    688                         irc_usermsg( irc, "The requested nick `%s' already exists", cmd[3] );
     689                        irc_rootmsg( irc, "The requested nick `%s' already exists", cmd[3] );
    689690                        return;
    690691                }
     
    704705                    strcmp( s, "group" ) == 0 &&
    705706                    ( group = set_getstr( &ic->set, "group" ) ) )
    706                         irc_usermsg( irc, "Adding `%s' to contact list (group %s)",
     707                        irc_rootmsg( irc, "Adding `%s' to contact list (group %s)",
    707708                                     cmd[2], group );
    708709                else
    709                         irc_usermsg( irc, "Adding `%s' to contact list", cmd[2] );
     710                        irc_rootmsg( irc, "Adding `%s' to contact list", cmd[2] );
    710711               
    711712                a->prpl->add_buddy( a->ic, cmd[2], group );
     
    720721                if( ( bu = bee_user_new( irc->b, a->ic, cmd[2], BEE_USER_LOCAL ) ) &&
    721722                    ( iu = bu->ui_data ) )
    722                         irc_usermsg( irc, "Temporarily assigned nickname `%s' "
     723                        irc_rootmsg( irc, "Temporarily assigned nickname `%s' "
    723724                                     "to contact `%s'", iu->nick, cmd[2] );
    724725        }
     
    734735        if( !( iu = irc_user_by_name( irc, cmd[1] ) ) || !( bu = iu->bu ) )
    735736        {
    736                 irc_usermsg( irc, "Buddy `%s' not found", cmd[1] );
     737                irc_rootmsg( irc, "Buddy `%s' not found", cmd[1] );
    737738                return;
    738739        }
     
    744745                bee_user_free( irc->b, bu );
    745746       
    746         irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );
     747        irc_rootmsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );
    747748        g_free( s );
    748749       
     
    760761                if( !iu || !iu->bu )
    761762                {
    762                         irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
     763                        irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] );
    763764                        return;
    764765                }
     
    768769        else if( !( a = account_get( irc->b, cmd[1] ) ) )
    769770        {
    770                 irc_usermsg( irc, "Invalid account" );
     771                irc_rootmsg( irc, "Invalid account" );
    771772                return;
    772773        }
    773774        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
    774775        {
    775                 irc_usermsg( irc, "That account is not on-line" );
     776                irc_rootmsg( irc, "That account is not on-line" );
    776777                return;
    777778        }
     
    779780        if( !ic->acc->prpl->get_info )
    780781        {
    781                 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     782                irc_rootmsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
    782783        }
    783784        else
     
    796797        if( iu == NULL )
    797798        {
    798                 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
     799                irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] );
    799800        }
    800801        else if( del )
     
    802803                if( iu->bu )
    803804                        bee_irc_user_nick_reset( iu );
    804                 irc_usermsg( irc, "Nickname reset to `%s'", iu->nick );
     805                irc_rootmsg( irc, "Nickname reset to `%s'", iu->nick );
    805806        }
    806807        else if( iu == irc->user )
    807808        {
    808                 irc_usermsg( irc, "Use /nick to change your own nickname" );
     809                irc_rootmsg( irc, "Use /nick to change your own nickname" );
    809810        }
    810811        else if( !nick_ok( cmd[2] ) )
    811812        {
    812                 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] );
     813                irc_rootmsg( irc, "Nick `%s' is invalid", cmd[2] );
    813814        }
    814815        else if( ( old = irc_user_by_name( irc, cmd[2] ) ) && old != iu )
    815816        {
    816                 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
     817                irc_rootmsg( irc, "Nick `%s' already exists", cmd[2] );
    817818        }
    818819        else
     
    820821                if( !irc_user_set_nick( iu, cmd[2] ) )
    821822                {
    822                         irc_usermsg( irc, "Error while changing nick" );
     823                        irc_rootmsg( irc, "Error while changing nick" );
    823824                        return;
    824825                }
     
    836837                }
    837838               
    838                 irc_usermsg( irc, "Nick successfully changed" );
     839                irc_rootmsg( irc, "Nick successfully changed" );
    839840        }
    840841}
     
    869870                        format = "%-32.32s  %-16.16s";
    870871               
    871                 irc_usermsg( irc, format, "Handle", "Nickname" );
     872                irc_rootmsg( irc, format, "Handle", "Nickname" );
    872873                for( l = a->ic->deny; l; l = l->next )
    873874                {
    874875                        bee_user_t *bu = bee_user_by_handle( irc->b, a->ic, l->data );
    875876                        irc_user_t *iu = bu ? bu->ui_data : NULL;
    876                         irc_usermsg( irc, format, l->data, iu ? iu->nick : "(none)" );
    877                 }
    878                 irc_usermsg( irc, "End of list." );
     877                        irc_rootmsg( irc, format, l->data, iu ? iu->nick : "(none)" );
     878                }
     879                irc_rootmsg( irc, "End of list." );
    879880               
    880881                return;
     
    885886                if( !iu || !iu->bu )
    886887                {
    887                         irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
     888                        irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] );
    888889                        return;
    889890                }
     
    893894        else if( !( a = account_get( irc->b, cmd[1] ) ) )
    894895        {
    895                 irc_usermsg( irc, "Invalid account" );
     896                irc_rootmsg( irc, "Invalid account" );
    896897                return;
    897898        }
    898899        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
    899900        {
    900                 irc_usermsg( irc, "That account is not on-line" );
     901                irc_rootmsg( irc, "That account is not on-line" );
    901902                return;
    902903        }
     
    904905        if( !ic->acc->prpl->add_deny || !ic->acc->prpl->rem_permit )
    905906        {
    906                 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     907                irc_rootmsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
    907908        }
    908909        else
     
    910911                imc_rem_allow( ic, cmd[2] );
    911912                imc_add_block( ic, cmd[2] );
    912                 irc_usermsg( irc, "Buddy `%s' moved from allow- to block-list", cmd[2] );
     913                irc_rootmsg( irc, "Buddy `%s' moved from allow- to block-list", cmd[2] );
    913914        }
    914915}
     
    929930                        format = "%-32.32s  %-16.16s";
    930931               
    931                 irc_usermsg( irc, format, "Handle", "Nickname" );
     932                irc_rootmsg( irc, format, "Handle", "Nickname" );
    932933                for( l = a->ic->permit; l; l = l->next )
    933934                {
    934935                        bee_user_t *bu = bee_user_by_handle( irc->b, a->ic, l->data );
    935936                        irc_user_t *iu = bu ? bu->ui_data : NULL;
    936                         irc_usermsg( irc, format, l->data, iu ? iu->nick : "(none)" );
    937                 }
    938                 irc_usermsg( irc, "End of list." );
     937                        irc_rootmsg( irc, format, l->data, iu ? iu->nick : "(none)" );
     938                }
     939                irc_rootmsg( irc, "End of list." );
    939940               
    940941                return;
     
    945946                if( !iu || !iu->bu )
    946947                {
    947                         irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
     948                        irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] );
    948949                        return;
    949950                }
     
    953954        else if( !( a = account_get( irc->b, cmd[1] ) ) )
    954955        {
    955                 irc_usermsg( irc, "Invalid account" );
     956                irc_rootmsg( irc, "Invalid account" );
    956957                return;
    957958        }
    958959        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
    959960        {
    960                 irc_usermsg( irc, "That account is not on-line" );
     961                irc_rootmsg( irc, "That account is not on-line" );
    961962                return;
    962963        }
     
    964965        if( !ic->acc->prpl->rem_deny || !ic->acc->prpl->add_permit )
    965966        {
    966                 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     967                irc_rootmsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
    967968        }
    968969        else
     
    971972                imc_add_allow( ic, cmd[2] );
    972973               
    973                 irc_usermsg( irc, "Buddy `%s' moved from block- to allow-list", cmd[2] );
     974                irc_rootmsg( irc, "Buddy `%s' moved from block- to allow-list", cmd[2] );
    974975        }
    975976}
     
    998999                        if( ( ++times >= 3 ) )
    9991000                        {
    1000                                 irc_usermsg( irc, "%s", msg[rand()%(sizeof(msg)/sizeof(char*))] );
     1001                                irc_rootmsg( irc, "%s", msg[rand()%(sizeof(msg)/sizeof(char*))] );
    10011002                                last_irc = NULL;
    10021003                                times = 0;
     
    10111012                }
    10121013               
    1013                 irc_usermsg( irc, "Did I ask you something?" );
     1014                irc_rootmsg( irc, "Did I ask you something?" );
    10141015                return;
    10151016        }
     
    10211022                if( sscanf( cmd[1], "%d", &numq ) != 1 )
    10221023                {
    1023                         irc_usermsg( irc, "Invalid query number" );
     1024                        irc_rootmsg( irc, "Invalid query number" );
    10241025                        return;
    10251026                }
     
    10311032                if( !q )
    10321033                {
    1033                         irc_usermsg( irc, "Uhm, I never asked you something like that..." );
     1034                        irc_rootmsg( irc, "Uhm, I never asked you something like that..." );
    10341035                        return;
    10351036                }
     
    10711072                format = "%-16.16s  %-40.40s  %s";
    10721073       
    1073         irc_usermsg( irc, format, "Nick", "Handle/Account", "Status" );
     1074        irc_rootmsg( irc, format, "Nick", "Handle/Account", "Status" );
    10741075       
    10751076        if( irc->root->last_channel &&
     
    10931094                                g_snprintf( st, sizeof( st ) - 1, "Online (%s)", bu->status_msg );
    10941095                       
    1095                         g_snprintf( s, sizeof( s ) - 1, "%s %s(%s)", bu->handle, bu->ic->acc->prpl->name, bu->ic->acc->user );
    1096                         irc_usermsg( irc, format, iu->nick, s, st );
     1096                        g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
     1097                        irc_rootmsg( irc, format, iu->nick, s, st );
    10971098                }
    10981099               
     
    11111112                if( away == 1 )
    11121113                {
    1113                         g_snprintf( s, sizeof( s ) - 1, "%s %s(%s)", bu->handle, bu->ic->acc->prpl->name, bu->ic->acc->user );
    1114                         irc_usermsg( irc, format, iu->nick, s, irc_user_get_away( iu ) );
     1114                        g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
     1115                        irc_rootmsg( irc, format, iu->nick, s, irc_user_get_away( iu ) );
    11151116                }
    11161117                n_away ++;
     
    11281129                if( offline == 1 )
    11291130                {
    1130                         g_snprintf( s, sizeof( s ) - 1, "%s %s(%s)", bu->handle, bu->ic->acc->prpl->name, bu->ic->acc->user );
    1131                         irc_usermsg( irc, format, iu->nick, s, "Offline" );
     1131                        g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
     1132                        irc_rootmsg( irc, format, iu->nick, s, "Offline" );
    11321133                }
    11331134                n_offline ++;
    11341135        }
    11351136       
    1136         irc_usermsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline );
     1137        irc_rootmsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline );
    11371138}
    11381139
     
    11441145        if( !q )
    11451146        {
    1146                 irc_usermsg( irc, "There are no pending questions." );
    1147                 return;
    1148         }
    1149        
    1150         irc_usermsg( irc, "Pending queries:" );
     1147                irc_rootmsg( irc, "There are no pending questions." );
     1148                return;
     1149        }
     1150       
     1151        irc_rootmsg( irc, "Pending queries:" );
    11511152       
    11521153        for( num = 0; q; q = q->next, num ++ )
    11531154                if( q->ic ) /* Not necessary yet, but it might come later */
    1154                         irc_usermsg( irc, "%d, %s(%s): %s", num, q->ic->acc->prpl->name, q->ic->acc->user, q->question );
    1155                 else
    1156                         irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
     1155                        irc_rootmsg( irc, "%d, %s: %s", num, q->ic->acc->tag, q->question );
     1156                else
     1157                        irc_rootmsg( irc, "%d, BitlBee: %s", num, q->question );
    11571158}
    11581159
     
    11701171                if( !( acc = account_get( irc->b, cmd[2] ) ) )
    11711172                {
    1172                         irc_usermsg( irc, "Invalid account" );
     1173                        irc_rootmsg( irc, "Invalid account" );
    11731174                        return;
    11741175                }
    11751176                else if( !acc->prpl->chat_join )
    11761177                {
    1177                         irc_usermsg( irc, "Named chatrooms not supported on that account." );
     1178                        irc_rootmsg( irc, "Named chatrooms not supported on that account." );
    11781179                        return;
    11791180                }
     
    12051206                    set_setstr( &ic->set, "room", cmd[3] ) )
    12061207                {
    1207                         irc_usermsg( irc, "Chatroom successfully added." );
     1208                        irc_rootmsg( irc, "Chatroom successfully added." );
    12081209                }
    12091210                else
     
    12121213                                irc_channel_free( ic );
    12131214                       
    1214                         irc_usermsg( irc, "Could not add chatroom." );
     1215                        irc_rootmsg( irc, "Could not add chatroom." );
    12151216                }
    12161217                g_free( channel );
     
    12271228                        if( !iu->bu->ic->acc->prpl->chat_with( iu->bu->ic, iu->bu->handle ) )
    12281229                        {
    1229                                 irc_usermsg( irc, "(Possible) failure while trying to open "
     1230                                irc_rootmsg( irc, "(Possible) failure while trying to open "
    12301231                                                  "a groupchat with %s.", iu->nick );
    12311232                        }
     
    12331234                else
    12341235                {
    1235                         irc_usermsg( irc, "Can't open a groupchat with %s.", cmd[2] );
     1236                        irc_rootmsg( irc, "Can't open a groupchat with %s.", cmd[2] );
    12361237                }
    12371238        }
     
    12401241                 g_strcasecmp( cmd[1], "del" ) == 0 )
    12411242        {
    1242                 irc_usermsg( irc, "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command." );
     1243                irc_rootmsg( irc, "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command." );
    12431244                cmd_channel( irc, cmd );
    12441245        }
    12451246        else
    12461247        {
    1247                 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] );
     1248                irc_rootmsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] );
    12481249        }
    12491250}
     
    12601261               
    12611262                if( strchr( irc->umode, 'b' ) )
    1262                         irc_usermsg( irc, "Group list:" );
     1263                        irc_rootmsg( irc, "Group list:" );
    12631264               
    12641265                for( l = irc->b->groups; l; l = l->next )
    12651266                {
    12661267                        bee_group_t *bg = l->data;
    1267                         irc_usermsg( irc, "%d. %s", n ++, bg->name );
    1268                 }
    1269                 irc_usermsg( irc, "End of group list" );
    1270         }
    1271         else
    1272         {
    1273                 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "group", cmd[1] );
     1268                        irc_rootmsg( irc, "%d. %s", n ++, bg->name );
     1269                }
     1270                irc_rootmsg( irc, "End of group list" );
     1271        }
     1272        else
     1273        {
     1274                irc_rootmsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "group", cmd[1] );
    12741275        }
    12751276}
     
    12841285        if( !files )
    12851286        {
    1286                 irc_usermsg( irc, "No pending transfers" );
     1287                irc_rootmsg( irc, "No pending transfers" );
    12871288                return;
    12881289        }
     
    13051306                case LIST:
    13061307                        if ( file->status == FT_STATUS_LISTENING )
    1307                                 irc_usermsg( irc,
     1308                                irc_rootmsg( irc,
    13081309                                        "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name);
    13091310                        else
     
    13141315                                        kb_per_s = file->bytes_transferred / 1024 / diff;
    13151316                                       
    1316                                 irc_usermsg( irc,
     1317                                irc_rootmsg( irc,
    13171318                                        "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name,
    13181319                                        file->bytes_transferred/1024, file->file_size/1024, kb_per_s);
     
    13221323                        if( file->status == FT_STATUS_LISTENING )
    13231324                        {
    1324                                 irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name );
     1325                                irc_rootmsg( irc, "Rejecting file transfer for %s", file->file_name );
    13251326                                imcb_file_canceled( file->ic, file, "Denied by user" );
    13261327                        }
     
    13291330                        if( file->local_id == fid )
    13301331                        {
    1331                                 irc_usermsg( irc, "Canceling file transfer for %s", file->file_name );
     1332                                irc_rootmsg( irc, "Canceling file transfer for %s", file->file_name );
    13321333                                imcb_file_canceled( file->ic, file, "Canceled by user" );
    13331334                        }
     
    13391340static void cmd_nick( irc_t *irc, char **cmd )
    13401341{
    1341     &nbs