Changeset dd34575


Ignore:
Timestamp:
2008-04-02T13:28:23Z (13 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
6ff51ff, 85d7b85
Parents:
0db75ad (diff), fa75134 (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:

merge trunk.

Files:
1 added
54 edited
2 moved

Legend:

Unmodified
Added
Removed
  • account.c

    r0db75ad rdd34575  
    182182        account_t *a, *l = NULL;
    183183       
     184        if( acc->ic )
     185                /* Caller should have checked, accounts still in use can't be deleted. */
     186                return;
     187       
    184188        for( a = irc->accounts; a; a = (l=a)->next )
    185189                if( a == acc )
    186190                {
    187                         if( a->ic ) return; /* Caller should have checked, accounts still in use can't be deleted. */
    188                        
    189191                        if( l )
    190                         {
    191192                                l->next = a->next;
    192                         }
    193193                        else
    194                         {
    195194                                irc->accounts = a->next;
    196                         }
    197195                       
    198196                        while( a->set )
     
    203201                        g_free( a->user );
    204202                        g_free( a->pass );
    205                         if( a->server ) g_free( a->server );
     203                        g_free( a->server );
    206204                        if( a->reconnect )      /* This prevents any reconnect still queued to happen */
    207205                                cancel_auto_reconnect( a );
  • bitlbee.conf

    r0db75ad rdd34575  
    4949##
    5050## Password the user should enter when logging into a closed BitlBee server.
     51## You can also have an MD5-encrypted password here. Format: "md5:", followed
     52## by a hash as generated for the <user password=""> attribute in a BitlBee
     53## XML file (for now there's no easier way to generate the hash).
    5154##
    5255# AuthPassword = ItllBeBitlBee   ## Heh.. Our slogan. ;-)
     56## or
     57# AuthPassword = md5:gzkK0Ox/1xh+1XTsQjXxBJ571Vgl
    5358
    5459## OperPassword
     
    5762##
    5863# OperPassword = ChangeMe!
     64## or
     65# OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX
    5966
    6067## HostName
  • bitlbee.h

    r0db75ad rdd34575  
    3030
    3131#define PACKAGE "BitlBee"
    32 #define BITLBEE_VERSION "1.1.1dev"
     32#define BITLBEE_VERSION "1.2"
    3333#define VERSION BITLBEE_VERSION
    3434
    35 #define MAX_STRING 128
     35#define MAX_STRING 511
    3636
    3737#if HAVE_CONFIG_H
  • conf.c

    r0db75ad rdd34575  
    252252                        {
    253253                                g_strfreev( conf->migrate_storage );
    254                                 conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
     254                                conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 );
    255255                        }
    256256                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
  • debian/README.Debian

    r0db75ad rdd34575  
    1                    *** NEWS (Version 1.1 and later) ***
     1                   *** NEWS (Version 1.2 and later) ***
    22
    3 Starting from version 1.1, BitlBee has a forking daemon mode. The Debian
     3Starting from version 1.2, BitlBee has a forking daemon mode. The Debian
    44package now uses this mode by default, instead of inetd mode. If you don't
    55want to use this, you can disable the init scripts (best way to do this is
     
    77should be necessary only once, it won't be touched during upgrades.
    88
    9 --------------------------------------------------------------------------
     9Another important change in BitlBee 1.2 is the file format used for your
     10personal settings. Everything's now saved in a single .xml (per account,
     11of course) file instead of $nick.accounts and $nick.nicks. One advantage
     12of this new format is that the passwords are actually encrypted instead of
     13just vaguely obfuscated. BitlBee can still read the old files, and will
     14save things in the new format when you save/disconnect. After that, you
     15can safely remove the old-style files (this is recommended).
     16
     17I tried making this transition (the new file format but especially, in this
     18case, the inetd->forkdaemon mode change) as smooth as possible, but I'm
     19aware that many BitlBee users will have their own hacks already to run the
     20program. I hope the package won't break any of this for anyone. 1.2-2
     21should fix at least some of the issues.
     22
     23---------------------------------------------------------------------------
    1024
    1125Debconf should have asked you on what port you want BitlBee to run. If it
  • debian/bitlbee.init

    r0db75ad rdd34575  
    11#! /bin/sh
     2### BEGIN INIT INFO
     3# Provides:          bitlbee
     4# Required-Start:    $remote_fs $syslog
     5# Required-Stop:     $remote_fs $syslog
     6# Default-Start:     2 3 4 5
     7# Default-Stop:      1
     8### END INIT INFO
    29#
    310# Init script for BitlBee Debian package. Based on skeleton init script:
     
    1825# Default value
    1926BITLBEE_PORT=6667
    20 DAEMON_OPT=-F
     27BITLBEE_OPTS=-F
    2128
    2229# Read config file if it is present.
     
    3744       
    3845        start-stop-daemon --start --quiet --pidfile $PIDFILE \
    39                 -c bitlbee -g nogroup \
    40                 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $DAEMON_OPT
     46                -c bitlbee: \
     47                --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS
    4148}
    4249
  • debian/changelog

    r0db75ad rdd34575  
    1 bitlbee (1.1.1dev-0pre) unstable; urgency=low
    2 
     1bitlbee (1.2-4) unstable; urgency=low
     2
     3  * Not a real release, just a placeholder for the changelog.
     4  * Fixed init script to use the BITLBEE_OPTS variable, not an undefined
     5    DAEMON_OPT.
     6  * Added dependency information to the init script. (Closes: #472567)
     7
     8 -- Wilmer van der Gaast <wilmer@gaast.net>  Sat, 29 Mar 2008 21:10:33 +0000
     9
     10bitlbee (1.2-3) unstable; urgency=low
     11
     12  * Removed DEB_BUILD_OPTIONS again (forgot to apply that change to the 1.2
     13    branch when I finished 1.0.4-2, things diverged too much anyway.)
     14    Closes: #472540.
     15
     16 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 24 Mar 2008 21:10:14 +0000
     17
     18bitlbee (1.2-2) unstable; urgency=low
     19
     20  * Fixed some packaging issues reported by IRC and e-mail. (Closes: #472373)
     21  * Fixed proxy support. (Closes: #472395)
     22  * Added a BitlBee group so only root can edit the configs and BitlBee can
     23    just *read* it.
     24  * Manually deleting /var/lib/bitlbee/ when purging, deluser doesn't want to
     25    do it.
     26
     27 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 24 Mar 2008 19:48:24 +0000
     28
     29bitlbee (1.2-1) unstable; urgency=low
     30
     31  * New upstream release. (Closes: #325017, #386914, #437515)
     32  * With hopefully completely sane charset handling (Closes: #296145)
    333  * Switched to the new forking daemon mode. Added /etc/default/bitlbee
    434    file, an init script. People who want to stick with inetd can do so, see
    535    the defaults file.
     36    (Closes: #460741, #466171, #294585, #345038, #306452, #392682)
    637  * Got rid of debconf Woody compatibility stuff.
    738  * No more MPL code in BitlBee, thanks to the Jabber module rewrite!
    8 
    9  -- Wilmer van der Gaast <wilmer@gaast.net>  Fri, 06 Jul 2007 09:09:36 +0100
     39  * Added Italian translation, sorry for taking so long! (Closes: #448238)
     40  * Added libevent dependency (more reliable event handling).
     41  * Removed GLib 1.x dependency because BitlBee really requires GLib >=2.4.
     42
     43 -- Wilmer van der Gaast <wilmer@gaast.net>  Tue, 18 Mar 2008 23:44:19 +0000
     44
     45bitlbee (1.0.4-2) unstable; urgency=low
     46
     47  * Removed $DEB_BUILD_OPTIONS because apparently buildds fill it with crap.
     48    (Closes: #458717)
     49
     50 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 11 Feb 2008 19:15:33 +0000
     51
     52bitlbee (1.0.4-1) unstable; urgency=low
     53
     54  * New upstream release.
     55  * Changed libnss-dev dependency. (Closes: #370442)
     56  * Added build-indep rule to debian/rules. (Closes: #395673)
     57
     58 -- Wilmer van der Gaast <wilmer@gaast.net>  Wed, 29 Aug 2007 20:24:28 +0100
    1059
    1160bitlbee (1.0.3-1.3) unstable; urgency=low
  • debian/conffiles

    r0db75ad rdd34575  
    11/etc/bitlbee/motd.txt
    22/etc/bitlbee/bitlbee.conf
     3/etc/init.d/bitlbee
  • debian/control

    r0db75ad rdd34575  
    44Maintainer: Wilmer van der Gaast <wilmer@gaast.net>
    55Standards-Version: 3.5.9
    6 Build-Depends: libglib2.0-dev | libglib-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf
     6Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf
    77
    88Package: bitlbee
  • debian/postinst

    r0db75ad rdd34575  
    1414BITLBEE_DISABLED=0
    1515BITLBEE_UPGRADE_DONT_RESTART=0
    16 [ -r /etc/default/bitlbee ] && source /etc/default/bitlbee
     16[ -r /etc/default/bitlbee ] && . /etc/default/bitlbee
    1717
    18 if [ "$BITLBEE_DISABLED" = "0" ]; then
    19         ## In case it's still there (if we're upgrading right now)
     18if [ "$BITLBEE_DISABLED" = "0" ] && type update-inetd > /dev/null 2> /dev/null &&
     19   ( expr "$2" : '0\..*' > /dev/null || expr "$2" : '1\.0\..*' > /dev/null ); then
     20        ## Make sure the inetd entry is gone (can still be there from a
     21        ## previous version.
    2022        update-inetd --remove '.*/usr/sbin/bitlbee'
     23        if grep -q /usr/sbin/bitlbee /etc/inetd.conf 2> /dev/null; then
     24                # Thanks for breaking update-inetd! (bugs.debian.org/311111)
     25                # I hope that it works at least with xinetd, because this
     26                # emergency hack doesn't:
     27                perl -pi -e 's:^[^#].*/usr/sbin/bitlbee$:## Now using daemon mode\: # $&:' /etc/inetd.conf
     28                killall -HUP inetd || true
     29        fi
    2130fi
    2231
     
    6574fi
    6675
    67 adduser --system --home /var/lib/bitlbee/ --disabled-login --disabled-password bitlbee
     76adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee
    6877chmod 700 /var/lib/bitlbee/
    6978
    7079## Can't do this in packaging phase: Don't know the UID yet. Access to
    71 ## the file should be limited, now that it stores passwords.
    72 chmod 600 /etc/bitlbee/bitlbee.conf
    73 chown bitlbee /etc/bitlbee/bitlbee.conf
     80## the file should be limited, now that it stores passwords. Added
     81## --group later for a little more security, but have to see if I can
     82## apply this change to existing installations on upgrades. Will think
     83## about that later.
     84if getent group bitlbee > /dev/null; then
     85        chmod 640 /etc/bitlbee/bitlbee.conf
     86        chown root:bitlbee /etc/bitlbee/bitlbee.conf
     87else
     88        chmod 600 /etc/bitlbee/bitlbee.conf
     89        chown bitlbee /etc/bitlbee/bitlbee.conf
     90fi
    7491
    7592if [ -z "$2" ]; then
  • debian/postrm

    r0db75ad rdd34575  
    99
    1010update-rc.d bitlbee remove > /dev/null 2>&1 || true
    11 deluser --remove-home bitlbee || true
     11rm -f /etc/default/bitlbee
     12
     13deluser --system --remove-home bitlbee || true
     14rm -rf /var/lib/bitlbee ## deluser doesn't seem to do this for homedirs in /var
  • debian/rules

    r0db75ad rdd34575  
    33DEBUG ?= 0
    44
     5ifdef BITLBEE_VERSION
     6BITLBEE_FORCE_VERSION=1
     7else
    58# Want to use the full package version number instead of just the release.
    69BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')"
    710export BITLBEE_VERSION
    8 
     11endif
    912
    1013build-arch: build-arch-stamp
    1114build-arch-stamp:
    1215        if [ ! -d debian ]; then exit 1; fi
    13         ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee $(DEB_BUILD_OPTIONS)
     16        ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent
    1417        $(MAKE)
    1518#       $(MAKE) -C doc/ all
     
    6669                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
    6770        dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee
    68 ifdef BITLBEE_VERSION
     71ifdef BITLBEE_FORCE_VERSION
    6972        dpkg-gencontrol -ldebian/changelog -isp -pbitlbee -Tdebian/bitlbee.substvars -Pdebian/bitlbee -v1:$(BITLBEE_VERSION)-0 -V'debconf-depends=debconf (>= 1.2.0) | debconf-2.0'
    7073else
  • doc/CHANGES

    r0db75ad rdd34575  
     1Version 1.2.1:
     2- Fixed proxy support.
     3- Fixed stalling issues while connecting to Jabber when using the OpenSSL
     4  module.
     5- Fixed problem with GLib and ForkDaemon where processes didn't die when
     6  the client disconnects.
     7- Fixed handling of "set charset none". (Which pretty much breaks the account
     8  completely in 1.2.)
     9- You can now automatically identify yourself to BitlBee by setting a server
     10  password in your IRC client.
     11- Compatible with all crazy kinds of line endings that clients can send.
     12
     13Finished ...
     14
    115Version 1.2:
    2 - First BitlBee development/testing RELEASE. This should be quite stable
    3   though (and for most people more stable than 1.0.x). It just has a couple
    4   of rough edges and needs a bit more testing.
    516- Added ForkDaemon mode next to the existing Daemon- and inetd modes. With
    617  ForkDaemon you can run BitlBee as a stand-alone daemon and every connection
     
    2132  1.x is so old that supporting it really isn't necessary anymore.
    2233- Many, many, MANY little changes, improvements, fixes. Using non-blocking
    23   I/O as much as possible, fixed lots of little bugs (including bugs that
    24   affected daemon mode stability). See the bzr logs for more information.
    25 - Added units tests, will have to add some more before the real release.
     34  I/O as much as possible, replaced the Gaim (0.59, IOW heavily outdated)
     35  API, fixed lots of little bugs (including bugs that affected daemon mode
     36  stability). See the bzr logs for more information.
     37- One of the user-visible changes from the API change: You can finally see
     38  all away states/messages properly.
     39- Added units tests. Test coverage is very minimal for now.
     40- Better charset handling: Everything is just converted from/to UTF-8 right
     41  in the IRC core, and charset mismatches are detected (if possible) and the
     42  user is asked to resolve this before continuing. Also, UTF-8 is the default
     43  setting now, since that's how the world seems to work these days.
     44- One can now keep hashed passwords in bitlbee.conf instead of the cleartext
     45  version.
    2646- Most important change: New file format for user data (accounts, nicks and
    2747  settings). Migration to the new format should happen transparently,
     
    6989  * An XML console (add xmlconsole to your contact list or see "help set
    7090    xmlconsole" if you want it permanently).
    71 
    72 Finished ???
     91- The Yahoo! module now says it supports YMSG protocol version 12, which will
     92  hopefully keep the Yahoo module working after 2008-04-02 (when Yahoo! is
     93  dropping support for version 6.x of their client).
     94- MSN switchboard handling changes. Hopefully less messages will get lost now,
     95  although things are still not perfect.
     96
     97Finished 17 Mar 2008
    7398
    7499Version 1.0.4:
  • doc/README

    r0db75ad rdd34575  
    4141by default) and chown it to the UID BitlBee is running as. Make sure this
    4242directory is read-/writable by this user only.
     43
     44--- (Fork)Daemon mode
     45
     46If you don't want to run any inetd daemon, you can run BitlBee in Daemon
     47mode. Right now, daemon mode may be a bad idea on servers with multiple
     48users, since possible fatal BitlBee bugs will crash the BitlBee process and
     49disconnect all connected users at once. Instead, you can use ForkDaemon
     50mode, which serves every user from a separate process, without depending on
     51an inetd daemon.
     52
     53To use BitlBee in daemon mode, just start it with the right flags or enable
     54it in bitlbee.conf. You probably want to write an init script to start
     55BitlBee automatically after a reboot. (This is where you realise using
     56a package from your distro would've been a better idea. :-P)
    4357
    4458
  • doc/user-guide/Support.xml

    r0db75ad rdd34575  
    44
    55<sect1>
    6 <title>BitlBee is beta software</title>
     6<title>Disclaimer</title>
    77
    88<para>
    9 Although BitlBee has quite some functionality it is still beta. That means it
    10 can crash at any time, corrupt your data or whatever. Don't use it in
    11 any production environment and don't rely on it.
     9BitlBee doesn't come with a warranty and is still (and will probably always
     10be) under development. That means it can crash at any time, corrupt your
     11data or whatever. Don't use it in any production environment and don't rely
     12on it, or at least don't blame us if things blow up. :-)
    1213</para>
    1314
  • doc/user-guide/commands.xml

    r0db75ad rdd34575  
    163163
    164164                        <para>
    165                                 If you want, you can also tell BitlBee what nick to give the new contact. Of course you can also use the <emphasis>rename</emphasis> command for that, but sometimes this might be more convenient.
    166                         </para>
    167                        
    168                         <para>
    169                                 Adding -tmp adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list.
     165                                If you want, you can also tell BitlBee what nick to give the new contact. The -tmp option adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. This normally won't show you any presence notifications.
    170166                        </para>
    171167                </description>
     
    383379
    384380        <bitlbee-setting name="charset" type="string" scope="global">
    385                 <default>iso8859-1</default>
     381                <default>utf-8</default>
    386382                <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values>
    387383
    388384                <description>
    389385                        <para>
    390                                 The charset setting enables you to use different character sets in BitlBee. These get converted to UTF-8 before sending and from UTF-8 when receiving.
    391                         </para>
    392 
    393                         <para>
    394                                 If you don't know what's the best value for this, at least iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://czyborra.com/charsets/iso8859.html
     386                                This setting tells BitlBee what your IRC client sends and expects. It should be equal to the charset setting of your IRC client if you want to be able to send and receive non-ASCII text properly.
     387                        </para>
     388
     389                        <para>
     390                                Most systems use UTF-8 these days. On older systems, an iso8859 charset may work better. For example, iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://www.unicodecharacter.com/charsets/iso8859.html
    395391                        </para>
    396392                </description>
     
    677673                <description>
    678674                        <para>
    679                                 Sends you a /notice when a user starts typing a message (if the protocol supports it, MSN for example). This is a bug, not a feature. (But please don't report it.. ;-) You don't want to use it. Really. In fact the typing-notification is just one of the least useful 'innovations' ever. It's just there because some guy will probably ask me about it anyway. ;-)
     675                                Sends you a /notice when a user starts typing a message (if supported by the IM protocol and the user's client). To use this, you most likely want to use a script in your IRC client to show this information in a more sensible way.
    680676                        </para>
    681677                </description>
     
    830826                <short-description>Change friendly name, nick</short-description>
    831827                <syntax>nick &lt;connection&gt; [&lt;new nick&gt;]</syntax>
    832                 <syntax>nick</syntax>
    833 
    834                 <description>
    835                         <para>
    836                                 This command allows to set the friendly name of an im account. If no new name is specified the command will report the current name. When the name contains spaces, don't forget to quote the whole nick in double quotes. Currently this command is only supported by the MSN protocol.
    837                         </para>
    838 
    839                         <para>
    840                                 It is recommended to use the per-account <emphasis>display_name</emphasis> setting to read and change this information. The <emphasis>nick</emphasis> command is deprecated.
     828                <syntax>nick &lt;connection&gt;</syntax>
     829
     830                <description>
     831                        <para>
     832                                Deprecated: Use the per-account <emphasis>display_name</emphasis> setting to read and change this information.
    841833                        </para>
    842834                </description>
    843835
    844836                <ircexample>
    845                         <ircline nick="wouter">nick 1 "Wouter Paesen"</ircline>
    846                         <ircline nick="root">Setting your name on connection 1 to `Wouter Paesen'</ircline>
     837                        <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline>
     838                        <ircline nick="root">display_name = `The majestik møøse'</ircline>
    847839                </ircexample>
    848840
  • doc/user-guide/misc.xml

    r0db75ad rdd34575  
    4747</variablelist>
    4848
    49 <para>
    50 This list was extracted from <ulink url="http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=">http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=</ulink>.
    51 </para>
    52 
    5349</sect1>
    5450
     
    5652<title>Groupchats</title>
    5753<para>
    58 Since version 0.8x, BitlBee supports groupchats on the MSN and Yahoo! networks. This text will try to explain you how they work.
     54BitlBee now supports groupchats on all IM networks. This text will try to explain you how they work.
    5955</para>
    6056
     
    7369
    7470<para>
    75 If you want to start a groupchat with the person <emphasis>jim_msn</emphasis> in it, just join the channel <emphasis>#jim_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and jim_msn in it.
     71If you want to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just join the channel <emphasis>#lisa_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and lisa_msn in it.
    7672</para>
    7773
     
    8278<para>
    8379Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>join_chat</emphasis> command to join them. See <emphasis>help join_chat</emphasis> for more information.
    84 </para>
    85 
    86 <para>
    87 This is all you'll probably need to know. If you have any problems, please read <emphasis>help groupchats3</emphasis>.
    88 </para>
    89 
    90 </sect1>
    91 
    92 <sect1 id="groupchats3">
    93 <title>Groupchat channel names</title>
    94 
    95 <para>
    96 Obviously the (numbered) channel names don't make a lot of sense. Problem is that groupchats usually don't have names at all in the IM-world, while IRC insists on a name. So BitlBee just generates something random, just don't pay attention to it. :-)
    97 </para>
    98 
    99 <para>
    100 Please also note that BitlBee doesn't support groupchats for all protocols yet. BitlBee will tell you so. Support for other protocols will hopefully come later.
    10180</para>
    10281
     
    121100        <member>On the phone, Phone, On phone</member>
    122101        <member>Out to lunch, Lunch, Food</member>
     102        <member>Invisible, Hidden</member>
    123103</simplelist>
    124104
     
    128108
    129109<para>
    130 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Protocols like Yahoo! and Jabber will also show this complete away message to your buddies.
     110You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Most IM-protocols can also show this additional information to your buddies.
    131111</para>
    132112
  • doc/user-guide/quickstart.xml

    r0db75ad rdd34575  
    6161
    6262<para>
    63 For most protocols (currently MSN, Jabber, Yahoo and AOL) BitlBee can download the contact list automatically from the IM server and all the on-line users should appear in the control channel when you log in.
     63Now 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.
    6464</para>
    6565
    6666<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.
     67BitlBee 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.
    6868</para>
    6969
     
    127127<ircexample>
    128128        <ircline nick="you">tux: hey, how's the weather down there?</ircline>
    129         <ircline nick="tux"> you: a bit chilly!</ircline>
     129        <ircline nick="tux">you: a bit chilly!</ircline>
    130130</ircexample>
    131131
    132132<para>
    133 If you'd rather chat with them in a separate window use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like you would for a private message in IRC.  If you want to have messages automatically come up in private messages rather than in the &amp;bitlbee channel, use the <emphasis>set private</emphasis> command: <emphasis>set private true</emphasis> (<emphasis>set private false</emphasis> to change back).
     133Note that, although all contacts are in the &amp;bitlbee channel, only tux will actually receive this message. The &amp;bitlbee channel shouldn't be confused with a real IRC channel.
     134</para>
     135
     136<para>
     137If you prefer chatting in a separate window, use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like on real IRC. BitlBee will remember how you talk to someone and show his/her responses the same way. If you want to change the default behaviour (for people you haven't talked to yet), see <emphasis>help set private</emphasis>.
    134138</para>
    135139
  • ipc.c

    r0db75ad rdd34575  
    258258        else
    259259        {
     260                ipc_master_free_fd( source );
     261        }
     262       
     263        return TRUE;
     264}
     265
     266gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )
     267{
     268        char *buf, **cmd;
     269       
     270        if( ( buf = ipc_readline( source ) ) )
     271        {
     272                cmd = irc_parse_line( buf );
     273                if( cmd )
     274                        ipc_command_exec( data, cmd, ipc_child_commands );
     275        }
     276        else
     277        {
     278                ipc_child_disable();
     279        }
     280       
     281        return TRUE;
     282}
     283
     284void ipc_to_master( char **cmd )
     285{
     286        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     287        {
     288                char *s = irc_build_line( cmd );
     289                ipc_to_master_str( "%s", s );
     290                g_free( s );
     291        }
     292        else if( global.conf->runmode == RUNMODE_DAEMON )
     293        {
     294                ipc_command_exec( NULL, cmd, ipc_master_commands );
     295        }
     296}
     297
     298void ipc_to_master_str( char *format, ... )
     299{
     300        char *msg_buf;
     301        va_list params;
     302
     303        va_start( params, format );
     304        msg_buf = g_strdup_vprintf( format, params );
     305        va_end( params );
     306       
     307        if( strlen( msg_buf ) > 512 )
     308        {
     309                /* Don't send it, it's too long... */
     310        }
     311        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
     312        {
     313                if( global.listen_socket >= 0 )
     314                        if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 )
     315                                ipc_child_disable();
     316        }
     317        else if( global.conf->runmode == RUNMODE_DAEMON )
     318        {
     319                char **cmd, *s;
     320               
     321                if( ( s = strchr( msg_buf, '\r' ) ) )
     322                        *s = 0;
     323               
     324                cmd = irc_parse_line( msg_buf );
     325                ipc_command_exec( NULL, cmd, ipc_master_commands );
     326                g_free( cmd );
     327        }
     328       
     329        g_free( msg_buf );
     330}
     331
     332void ipc_to_children( char **cmd )
     333{
     334        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     335        {
     336                char *msg_buf = irc_build_line( cmd );
     337                ipc_to_children_str( "%s", msg_buf );
     338                g_free( msg_buf );
     339        }
     340        else if( global.conf->runmode == RUNMODE_DAEMON )
     341        {
    260342                GSList *l;
    261                 struct bitlbee_child *c;
    262                
    263                 for( l = child_list; l; l = l->next )
     343               
     344                for( l = irc_connection_list; l; l = l->next )
     345                        ipc_command_exec( l->data, cmd, ipc_child_commands );
     346        }
     347}
     348
     349void ipc_to_children_str( char *format, ... )
     350{
     351        char *msg_buf;
     352        va_list params;
     353
     354        va_start( params, format );
     355        msg_buf = g_strdup_vprintf( format, params );
     356        va_end( params );
     357       
     358        if( strlen( msg_buf ) > 512 )
     359        {
     360                /* Don't send it, it's too long... */
     361        }
     362        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
     363        {
     364                int msg_len = strlen( msg_buf );
     365                GSList *l, *next;
     366               
     367                for( l = child_list; l; l = next )
    264368                {
    265                         c = l->data;
    266                         if( c->ipc_fd == source )
     369                        struct bitlbee_child *c = l->data;
     370                       
     371                        next = l->next;
     372                        if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 )
    267373                        {
    268374                                ipc_master_free_one( c );
    269375                                child_list = g_slist_remove( child_list, c );
    270                                 break;
    271376                        }
    272                 }
    273         }
    274        
    275         return TRUE;
    276 }
    277 
    278 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )
    279 {
    280         char *buf, **cmd;
    281        
    282         if( ( buf = ipc_readline( source ) ) )
    283         {
    284                 cmd = irc_parse_line( buf );
    285                 if( cmd )
    286                         ipc_command_exec( data, cmd, ipc_child_commands );
    287         }
    288         else
    289         {
    290                 b_event_remove( global.listen_watch_source_id );
    291                 close( global.listen_socket );
    292                
    293                 global.listen_socket = -1;
    294         }
    295        
    296         return TRUE;
    297 }
    298 
    299 void ipc_to_master( char **cmd )
    300 {
    301         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    302         {
    303                 char *s = irc_build_line( cmd );
    304                 ipc_to_master_str( "%s", s );
    305                 g_free( s );
    306         }
    307         else if( global.conf->runmode == RUNMODE_DAEMON )
    308         {
    309                 ipc_command_exec( NULL, cmd, ipc_master_commands );
    310         }
    311 }
    312 
    313 void ipc_to_master_str( char *format, ... )
    314 {
    315         char *msg_buf;
    316         va_list params;
    317 
    318         va_start( params, format );
    319         msg_buf = g_strdup_vprintf( format, params );
    320         va_end( params );
    321        
    322         if( strlen( msg_buf ) > 512 )
    323         {
    324                 /* Don't send it, it's too long... */
    325         }
    326         else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    327         {
    328                 write( global.listen_socket, msg_buf, strlen( msg_buf ) );
    329         }
    330         else if( global.conf->runmode == RUNMODE_DAEMON )
    331         {
    332                 char **cmd, *s;
    333                
    334                 if( ( s = strchr( msg_buf, '\r' ) ) )
    335                         *s = 0;
    336                
    337                 cmd = irc_parse_line( msg_buf );
    338                 ipc_command_exec( NULL, cmd, ipc_master_commands );
    339                 g_free( cmd );
    340         }
    341        
    342         g_free( msg_buf );
    343 }
    344 
    345 void ipc_to_children( char **cmd )
    346 {
    347         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    348         {
    349                 char *msg_buf = irc_build_line( cmd );
    350                 ipc_to_children_str( "%s", msg_buf );
    351                 g_free( msg_buf );
    352         }
    353         else if( global.conf->runmode == RUNMODE_DAEMON )
    354         {
    355                 GSList *l;
    356                
    357                 for( l = irc_connection_list; l; l = l->next )
    358                         ipc_command_exec( l->data, cmd, ipc_child_commands );
    359         }
    360 }
    361 
    362 void ipc_to_children_str( char *format, ... )
    363 {
    364         char *msg_buf;
    365         va_list params;
    366 
    367         va_start( params, format );
    368         msg_buf = g_strdup_vprintf( format, params );
    369         va_end( params );
    370        
    371         if( strlen( msg_buf ) > 512 )
    372         {
    373                 /* Don't send it, it's too long... */
    374         }
    375         else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    376         {
    377                 int msg_len = strlen( msg_buf );
    378                 GSList *l;
    379                
    380                 for( l = child_list; l; l = l->next )
    381                 {
    382                         struct bitlbee_child *c = l->data;
    383                         write( c->ipc_fd, msg_buf, msg_len );
    384377                }
    385378        }
     
    410403}
    411404
     405void ipc_master_free_fd( int fd )
     406{
     407        GSList *l;
     408        struct bitlbee_child *c;
     409       
     410        for( l = child_list; l; l = l->next )
     411        {
     412                c = l->data;
     413                if( c->ipc_fd == fd )
     414                {
     415                        ipc_master_free_one( c );
     416                        child_list = g_slist_remove( child_list, c );
     417                        break;
     418                }
     419        }
     420}
     421
    412422void ipc_master_free_all()
    413423{
     
    419429        g_slist_free( child_list );
    420430        child_list = NULL;
     431}
     432
     433void ipc_child_disable()
     434{
     435        b_event_remove( global.listen_watch_source_id );
     436        close( global.listen_socket );
     437       
     438        global.listen_socket = -1;
    421439}
    422440
  • ipc.h

    r0db75ad rdd34575  
    4444
    4545void ipc_master_free_one( struct bitlbee_child *child );
     46void ipc_master_free_fd( int fd );
    4647void ipc_master_free_all();
     48
     49void ipc_child_disable();
    4750
    4851void ipc_to_master( char **cmd );
  • irc.c

    r0db75ad rdd34575  
    4242}
    4343
     44static char *set_eval_charset( set_t *set, char *value )
     45{
     46        irc_t *irc = set->data;
     47        GIConv ic, oc;
     48
     49        if( g_strcasecmp( value, "none" ) == 0 )
     50                value = g_strdup( "utf-8" );
     51
     52        if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 )
     53        {
     54                return NULL;
     55        }
     56        if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
     57        {
     58                g_iconv_close( ic );
     59                return NULL;
     60        }
     61       
     62        if( irc->iconv != (GIConv) -1 )
     63                g_iconv_close( irc->iconv );
     64        if( irc->oconv != (GIConv) -1 )
     65                g_iconv_close( irc->oconv );
     66       
     67        irc->iconv = ic;
     68        irc->oconv = oc;
     69
     70        return value;
     71}
     72
    4473irc_t *irc_new( int fd )
    4574{
     
    6493        irc->mynick = g_strdup( ROOT_NICK );
    6594        irc->channel = g_strdup( ROOT_CHAN );
     95       
     96        irc->iconv = (GIConv) -1;
     97        irc->oconv = (GIConv) -1;
    6698       
    6799        if( global.conf->hostname )
     
    127159        conf_loaddefaults( irc );
    128160       
     161        /* Evaluator sets the iconv/oconv structures. */
     162        set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) );
     163       
    129164        return( irc );
    130165}
     
    185220
    186221/* Because we have no garbage collection, this is quite annoying */
    187 void irc_free(irc_t * irc)
    188 {
    189         account_t *account;
     222void irc_free( irc_t * irc )
     223{
    190224        user_t *user, *usertmp;
    191225       
     
    196230                        irc_usermsg( irc, "Error while saving settings!" );
    197231       
    198         closesocket( irc->fd );
     232        irc_connection_list = g_slist_remove( irc_connection_list, irc );
     233       
     234        while( irc->accounts )
     235        {
     236                if( irc->accounts->ic )
     237                        imc_logout( irc->accounts->ic, FALSE );
     238                else if( irc->accounts->reconnect )
     239                        cancel_auto_reconnect( irc->accounts );
     240               
     241                if( irc->accounts->ic == NULL )
     242                        account_del( irc, irc->accounts );
     243                else
     244                        /* Nasty hack, but account_del() doesn't work in this
     245                           case and we don't want infinite loops, do we? ;-) */
     246                        irc->accounts = irc->accounts->next;
     247        }
     248       
     249        while( irc->queries != NULL )
     250                query_del( irc, irc->queries );
     251       
     252        while( irc->set )
     253                set_del( &irc->set, irc->set->key );
     254       
     255        if (irc->users != NULL)
     256        {
     257                user = irc->users;
     258                while( user != NULL )
     259                {
     260                        g_free( user->nick );
     261                        g_free( user->away );
     262                        g_free( user->handle );
     263                        if( user->user != user->nick ) g_free( user->user );
     264                        if( user->host != user->nick ) g_free( user->host );
     265                        if( user->realname != user->nick ) g_free( user->realname );
     266                        b_event_remove( user->sendbuf_timer );
     267                                       
     268                        usertmp = user;
     269                        user = user->next;
     270                        g_free( usertmp );
     271                }
     272        }
    199273       
    200274        if( irc->ping_source_id > 0 )
     
    204278                b_event_remove( irc->w_watch_source_id );
    205279       
    206         irc_connection_list = g_slist_remove( irc_connection_list, irc );
    207        
    208         for (account = irc->accounts; account; account = account->next) {
    209                 if (account->ic) {
    210                         imc_logout(account->ic, TRUE);
    211                 } else if (account->reconnect) {
    212                         cancel_auto_reconnect(account);
    213                 }
    214         }
    215        
    216         g_free(irc->sendbuffer);
    217         g_free(irc->readbuffer);
    218        
    219         g_free(irc->nick);
    220         g_free(irc->user);
    221         g_free(irc->host);
    222         g_free(irc->realname);
    223         g_free(irc->password);
    224        
    225         g_free(irc->myhost);
    226         g_free(irc->mynick);
    227        
    228         g_free(irc->channel);
    229        
    230         while (irc->queries != NULL)
    231                 query_del(irc, irc->queries);
    232        
    233         while (irc->accounts)
    234                 if (irc->accounts->ic == NULL)
    235                         account_del(irc, irc->accounts);
    236                 else
    237                         /* Nasty hack, but account_del() doesn't work in this
    238                            case and we don't want infinite loops, do we? ;-) */
    239                         irc->accounts = irc->accounts->next;
    240        
    241         while (irc->set)
    242                 set_del(&irc->set, irc->set->key);
    243        
    244         if (irc->users != NULL) {
    245                 user = irc->users;
    246                 while (user != NULL) {
    247                         g_free(user->nick);
    248                         g_free(user->away);
    249                         g_free(user->handle);
    250                         if(user->user!=user->nick) g_free(user->user);
    251                         if(user->host!=user->nick) g_free(user->host);
    252                         if(user->realname!=user->nick) g_free(user->realname);
    253                         b_event_remove(user->sendbuf_timer);
    254                                        
    255                         usertmp = user;
    256                         user = user->next;
    257                         g_free(usertmp);
    258                 }
    259         }
    260        
    261         g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL);
    262         g_hash_table_destroy(irc->userhash);
    263        
    264         g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL);
    265         g_hash_table_destroy(irc->watches);
    266        
    267         g_free(irc);
     280        closesocket( irc->fd );
     281        irc->fd = -1;
     282       
     283        g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL );
     284        g_hash_table_destroy( irc->userhash );
     285       
     286        g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL );
     287        g_hash_table_destroy( irc->watches );
     288       
     289        if( irc->iconv != (GIConv) -1 )
     290                g_iconv_close( irc->iconv );
     291        if( irc->oconv != (GIConv) -1 )
     292                g_iconv_close( irc->oconv );
     293       
     294        g_free( irc->sendbuffer );
     295        g_free( irc->readbuffer );
     296       
     297        g_free( irc->nick );
     298        g_free( irc->user );
     299        g_free( irc->host );
     300        g_free( irc->realname );
     301        g_free( irc->password );
     302       
     303        g_free( irc->myhost );
     304        g_free( irc->mynick );
     305       
     306        g_free( irc->channel );
     307       
     308        g_free( irc->last_target );
     309       
     310        g_free( irc );
    268311       
    269312        if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON )
     
    286329void irc_process( irc_t *irc )
    287330{
    288         char **lines, *temp, **cmd, *cs;
     331        char **lines, *temp, **cmd;
    289332        int i;
    290333
     
    295338                for( i = 0; *lines[i] != '\0'; i ++ )
    296339                {
    297                         char conv[IRC_MAX_LINE+1];
     340                        char *conv = NULL;
    298341                       
    299                         /* [WvG] Because irc_tokenize splits at every newline, the lines[] list
    300                             should end with an empty string. This is why this actually works.
    301                             Took me a while to figure out, Maurits. :-P */
     342                        /* [WvG] If the last line isn't empty, it's an incomplete line and we
     343                           should wait for the rest to come in before processing it. */
    302344                        if( lines[i+1] == NULL )
    303345                        {
     
    309351                        }
    310352                       
    311                         if( ( cs = set_getstr( &irc->set, "charset" ) ) )
    312                         {
    313                                 conv[IRC_MAX_LINE] = 0;
    314                                 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 )
     353                        if( irc->iconv != (GIConv) -1 )
     354                        {
     355                                gsize bytes_read, bytes_written;
     356                               
     357                                conv = g_convert_with_iconv( lines[i], -1, irc->iconv,
     358                                                             &bytes_read, &bytes_written, NULL );
     359                               
     360                                if( conv == NULL || bytes_read != strlen( lines[i] ) )
    315361                                {
    316362                                        /* GLib can do strange things if things are not in the expected charset,
     
    324370                                                                  "expect by changing the charset setting. See "
    325371                                                                  "`help set charset' for more information. Your "
    326                                                                   "message was ignored.", cs );
    327                                                 *conv = 0;
     372                                                                  "message was ignored.",
     373                                                                  set_getstr( &irc->set, "charset" ) );
     374                                               
     375                                                g_free( conv );
     376                                                conv = NULL;
    328377                                        }
    329378                                        else
    330379                                        {
    331380                                                irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost,
    332                                                            "Warning: invalid (non-UTF8) characters received at login time." );
     381                                                           "Warning: invalid characters received at login time." );
    333382                                               
    334                                                 strncpy( conv, lines[i], IRC_MAX_LINE );
     383                                                conv = g_strdup( lines[i] );
    335384                                                for( temp = conv; *temp; temp ++ )
    336385                                                        if( *temp & 0x80 )
     
    341390                        }
    342391                       
    343                         if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    344                                 continue;
    345                         irc_exec( irc, cmd );
     392                        if( lines[i] )
     393                        {
     394                                if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
     395                                        continue;
     396                                irc_exec( irc, cmd );
     397                                g_free( cmd );
     398                        }
    346399                       
    347                         g_free( cmd );
     400                        g_free( conv );
    348401                       
    349402                        /* Shouldn't really happen, but just in case... */
     
    369422char **irc_tokenize( char *buffer )
    370423{
    371         int i, j;
     424        int i, j, n = 3;
    372425        char **lines;
    373426
    374         /* Count the number of elements we're gonna need. */
    375         for( i = 0, j = 1; buffer[i] != '\0'; i ++ )
    376         {
    377                 if( buffer[i] == '\n' )
    378                         if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
    379                                 j ++;
    380         }
    381        
    382         /* Allocate j+1 elements. */
    383         lines = g_new( char *, j + 1 );
     427        /* Allocate n+1 elements. */
     428        lines = g_new( char *, n + 1 );
     429       
     430        lines[0] = buffer;
     431       
     432        /* Split the buffer in several strings, and accept any kind of line endings,
     433         * knowing that ERC on Windows may send something interesting like \r\r\n,
     434         * and surely there must be clients that think just \n is enough... */
     435        for( i = 0, j = 0; buffer[i] != '\0'; i ++ )
     436        {
     437                if( buffer[i] == '\r' || buffer[i] == '\n' )
     438                {
     439                        while( buffer[i] == '\r' || buffer[i] == '\n' )
     440                                buffer[i++] = '\0';
     441                       
     442                        lines[++j] = buffer + i;
     443                       
     444                        if( j >= n )
     445                        {
     446                                n *= 2;
     447                                lines = g_renew( char *, lines, n + 1 );
     448                        }
     449
     450                        if( buffer[i] == '\0' )
     451                                break;
     452                }
     453        }
    384454       
    385455        /* NULL terminate our list. */
    386         lines[j] = NULL;
    387        
    388         lines[0] = buffer;
    389        
    390         /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
    391          * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
    392          */
    393         for( i = 0, j = 0; buffer[i] != '\0'; i ++)
    394         {
    395                 if( buffer[i] == '\n' )
    396                 {
    397                         buffer[i] = '\0';
    398                        
    399                         if( i > 0 && buffer[i-1] == '\r' )
    400                                 buffer[i-1] = '\0';
    401                         if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
    402                                 lines[++j] = buffer + i + 1;
    403                 }
    404         }
    405        
    406         return( lines );
     456        lines[++j] = NULL;
     457       
     458        return lines;
    407459}
    408460
     
    538590
    539591        return;
    540 
    541592}
    542593
     
    544595{
    545596        int size;
    546         char line[IRC_MAX_LINE+1], *cs;
     597        char line[IRC_MAX_LINE+1];
    547598               
    548599        /* Don't try to write anything new anymore when shutting down. */
     
    550601                return;
    551602       
    552         line[IRC_MAX_LINE] = 0;
     603        memset( line, 0, sizeof( line ) );
    553604        g_vsnprintf( line, IRC_MAX_LINE - 2, format, params );
    554        
    555605        strip_newlines( line );
    556         if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
    557         {
    558                 char conv[IRC_MAX_LINE+1];
    559                
    560                 conv[IRC_MAX_LINE] = 0;
    561                 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 )
    562                         strcpy( line, conv );
    563         }
    564         strcat( line, "\r\n" );
     606       
     607        if( irc->oconv != (GIConv) -1 )
     608        {
     609                gsize bytes_read, bytes_written;
     610                char *conv;
     611               
     612                conv = g_convert_with_iconv( line, -1, irc->oconv,
     613                                             &bytes_read, &bytes_written, NULL );
     614
     615                if( bytes_read == strlen( line ) )
     616                        strncpy( line, conv, IRC_MAX_LINE - 2 );
     617               
     618                g_free( conv );
     619        }
     620        g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 );
    565621       
    566622        if( irc->sendbuffer != NULL )
     
    735791        irc_spawn( irc, u );
    736792       
    737         irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there." );
     793        irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n"
     794                          "If you've never used BitlBee before, please do read the help "
     795                          "information using the \x02help\x02 command. Lots of FAQs are "
     796                          "answered there.\n"
     797                          "If you already have an account on this server, just use the "
     798                          "\x02identify\x02 command to identify yourself." );
    738799       
    739800        if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON )
     
    741802       
    742803        irc->status |= USTATUS_LOGGED_IN;
     804       
     805        /* This is for bug #209 (use PASS to identify to NickServ). */
     806        if( irc->password != NULL )
     807        {
     808                char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL };
     809               
     810                irc_setpass( irc, NULL );
     811                root_command( irc, send_cmd );
     812                g_free( send_cmd[1] );
     813        }
    743814}
    744815
  • irc.h

    r0db75ad rdd34575  
    6161        char *sendbuffer;
    6262        char *readbuffer;
     63        GIConv iconv, oconv;
    6364
    6465        int sentbytes;
     
    6970        char *host;
    7071        char *realname;
    71         char *password;
     72        char *password; /* HACK: Used to save the user's password, but before
     73                           logging in, this may contain a password we should
     74                           send to identify after USER/NICK are received. */
    7275
    7376        char umode[8];
  • irc_commands.c

    r0db75ad rdd34575  
    3030static void irc_cmd_pass( irc_t *irc, char **cmd )
    3131{
    32         if( global.conf->auth_pass && strcmp( cmd[1], global.conf->auth_pass ) == 0 )
     32        if( irc->status & USTATUS_LOGGED_IN )
     33        {
     34                char *send_cmd[] = { "identify", cmd[1], NULL };
     35               
     36                /* We're already logged in, this client seems to send the PASS
     37                   command last. (Possibly it won't send it at all if it turns
     38                   out we don't require it, which will break this feature.)
     39                   Try to identify using the given password. */
     40                return root_command( irc, send_cmd );
     41        }
     42        /* Handling in pre-logged-in state, first see if this server is
     43           password-protected: */
     44        else if( global.conf->auth_pass &&
     45            ( strncmp( global.conf->auth_pass, "md5:", 4 ) == 0 ?
     46                md5_verify_password( cmd[1], global.conf->auth_pass + 4 ) == 0 :
     47                strcmp( cmd[1], global.conf->auth_pass ) == 0 ) )
    3348        {
    3449                irc->status |= USTATUS_AUTHORIZED;
    3550                irc_check_login( irc );
    3651        }
    37         else
     52        else if( global.conf->auth_pass )
    3853        {
    3954                irc_reply( irc, 464, ":Incorrect password" );
     55        }
     56        else
     57        {
     58                /* Remember the password and try to identify after USER/NICK. */
     59                irc_setpass( irc, cmd[1] );
     60                irc_check_login( irc );
    4061        }
    4162}
     
    88109static void irc_cmd_oper( irc_t *irc, char **cmd )
    89110{
    90         if( global.conf->oper_pass && strcmp( cmd[2], global.conf->oper_pass ) == 0 )
     111        if( global.conf->oper_pass &&
     112            ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
     113                md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
     114                strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
    91115        {
    92116                irc_umode_set( irc, "+o", 1 );
     
    254278                        if( cmd[1] != irc->last_target )
    255279                        {
    256                                 if( irc->last_target )
    257                                         g_free( irc->last_target );
     280                                g_free( irc->last_target );
    258281                                irc->last_target = g_strdup( cmd[1] );
    259282                        }
     
    575598
    576599static const command_t irc_commands[] = {
    577         { "pass",        1, irc_cmd_pass,        IRC_CMD_PRE_LOGIN },
     600        { "pass",        1, irc_cmd_pass,        0 },
    578601        { "user",        4, irc_cmd_user,        IRC_CMD_PRE_LOGIN },
    579602        { "nick",        1, irc_cmd_nick,        0 },
  • lib/Makefile

    r0db75ad rdd34575  
    1010
    1111# [SH] Program variables
    12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o
     12objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
    1313
    1414CFLAGS += -Wall
  • lib/arc.c

    r0db75ad rdd34575  
    131131   
    132132   Both functions return the number of bytes in the result string.
     133   
     134   Note that if you use the pad_to argument, you will need zero-termi-
     135   nation to find back the original string length after decryption. So
     136   it shouldn't be used if your string contains \0s by itself!
    133137*/
    134138
    135 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password )
     139int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to )
    136140{
    137141        struct arc_state *st;
    138142        unsigned char *key;
    139         int key_len, i;
     143        char *padded = NULL;
     144        int key_len, i, padded_len;
    140145       
    141146        key_len = strlen( password ) + ARC_IV_LEN;
    142147        if( clear_len <= 0 )
    143148                clear_len = strlen( clear );
     149       
     150        /* Pad the string to the closest multiple of pad_to. This makes it
     151           impossible to see the exact length of the password. */
     152        if( pad_to > 0 && ( clear_len % pad_to ) > 0 )
     153        {
     154                padded_len = clear_len + pad_to - ( clear_len % pad_to );
     155                padded = g_malloc( padded_len );
     156                memcpy( padded, clear, clear_len );
     157               
     158                /* First a \0 and then random data, so we don't have to do
     159                   anything special when decrypting. */
     160                padded[clear_len] = 0;
     161                random_bytes( (unsigned char*) padded + clear_len + 1, padded_len - clear_len - 1 );
     162               
     163                clear = padded;
     164                clear_len = padded_len;
     165        }
    144166       
    145167        /* Prepare buffers and the key + IV */
     
    161183       
    162184        g_free( st );
     185        g_free( padded );
    163186       
    164187        return clear_len + ARC_IV_LEN;
  • lib/arc.h

    r0db75ad rdd34575  
    3131};
    3232
    33 struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
     33G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
    3434unsigned char arc_getbyte( struct arc_state *st );
    35 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password );
     35int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to );
    3636int arc_decode( unsigned char *crypt, int crypt_len, char **clear, char *password );
  • lib/base64.c

    r0db75ad rdd34575  
    118118        int i, outlen = 0;
    119119       
    120         for( i = 0; in[i]; i += 4 )
     120        for( i = 0; in[i] && in[i+1] && in[i+2] && in[i+3]; i += 4 )
    121121        {
    122122                int sx;
  • lib/events_glib.c

    r0db75ad rdd34575  
    5151} GaimIOClosure;
    5252
    53 static GMainLoop *loop;
     53static GMainLoop *loop = NULL;
    5454
    5555void b_main_init()
    5656{
    57         loop = g_main_new( FALSE );
     57        if( loop == NULL )
     58                loop = g_main_new( FALSE );
    5859}
    5960
  • lib/misc.c

    r0db75ad rdd34575  
    3333#define BITLBEE_CORE
    3434#include "nogaim.h"
     35#include "base64.h"
    3536#include <stdio.h>
    3637#include <stdlib.h>
     
    597598                return sockerr_again();
    598599}
     600
     601/* Returns values: -1 == Failure (base64-decoded to something unexpected)
     602                    0 == Okay
     603                    1 == Password doesn't match the hash. */
     604int md5_verify_password( char *password, char *hash )
     605{
     606        md5_byte_t *pass_dec = NULL;
     607        md5_byte_t pass_md5[16];
     608        md5_state_t md5_state;
     609        int ret, i;
     610       
     611        if( base64_decode( hash, &pass_dec ) != 21 )
     612        {
     613                ret = -1;
     614        }
     615        else
     616        {
     617                md5_init( &md5_state );
     618                md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) );
     619                md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */
     620                md5_finish( &md5_state, pass_md5 );
     621               
     622                for( i = 0; i < 16; i ++ )
     623                {
     624                        if( pass_dec[i] != pass_md5[i] )
     625                        {
     626                                ret = 1;
     627                                break;
     628                        }
     629                }
     630               
     631                /* If we reached the end of the loop, it was a match! */
     632                if( i == 16 )
     633                        ret = 0;
     634        }
     635       
     636        g_free( pass_dec );
     637
     638        return ret;
     639}
  • lib/misc.h

    r0db75ad rdd34575  
    6767G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl );
    6868
     69G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
     70
    6971#endif
  • lib/proxy.c

    r0db75ad rdd34575  
    530530        struct PHB *phb;
    531531       
    532         if (!host || !port || (port == -1) || !func || strlen(host) > 128) {
     532        if (!host || port <= 0 || !func || strlen(host) > 128) {
    533533                return -1;
    534534        }
     
    538538        phb->data = data;
    539539       
    540         if ((proxytype == PROXY_NONE) || strlen(proxyhost) > 0 || !proxyport || (proxyport == -1))
     540        if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0)
    541541                return proxy_connect_none(host, port, phb);
    542542        else if (proxytype == PROXY_HTTP)
  • lib/ssl_client.h

    r0db75ad rdd34575  
    6060G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
    6161
     62/* See ssl_openssl.c for an explanation. */
     63G_MODULE_EXPORT int ssl_pending( void *conn );
     64
    6265/* Abort the SSL connection and disconnect the socket. Do not use close()
    6366   directly, both the SSL library and the peer will be unhappy! */
  • lib/ssl_gnutls.c

    r0db75ad rdd34575  
    211211}
    212212
     213/* See ssl_openssl.c for an explanation. */
     214int ssl_pending( void *conn )
     215{
     216        return 0;
     217}
     218
    213219void ssl_disconnect( void *conn_ )
    214220{
  • lib/ssl_nss.c

    r0db75ad rdd34575  
    169169}
    170170
     171/* See ssl_openssl.c for an explanation. */
     172int ssl_pending( void *conn )
     173{
     174        return 0;
     175}
     176
    171177void ssl_disconnect( void *conn_ )
    172178{
  • lib/ssl_openssl.c

    r0db75ad rdd34575  
    6262       
    6363        conn->fd = proxy_connect( host, port, ssl_connected, conn );
     64        if( conn->fd < 0 )
     65        {
     66                g_free( conn );
     67                return NULL;
     68        }
     69       
    6470        conn->func = func;
    6571        conn->data = data;
    6672        conn->inpa = -1;
    67        
    68         if( conn->fd < 0 )
    69         {
    70                 g_free( conn );
    71                 return NULL;
    72         }
    7373       
    7474        return conn;
     
    231231}
    232232
     233/* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info:
     234   http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
     235   http://www.openssl.org/docs/ssl/SSL_pending.html
     236   
     237   Required because OpenSSL empties the TCP buffer completely but doesn't
     238   necessarily give us all the unencrypted data.
     239   
     240   Returns 0 if there's nothing left or if we don't have to care (GnuTLS),
     241   1 if there's more data. */
     242int ssl_pending( void *conn )
     243{
     244        return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ?
     245               SSL_pending( ((struct scd*)conn)->ssl ) > 0 : 0;
     246}
     247
    233248void ssl_disconnect( void *conn_ )
    234249{
  • lib/url.c

    r0db75ad rdd34575  
    2626#include "url.h"
    2727
    28 /* Convert an URL to a url_t structure                                  */
     28/* Convert an URL to a url_t structure */
    2929int url_set( url_t *url, char *set_url )
    3030{
    31         char s[MAX_STRING];
     31        char s[MAX_STRING+1];
    3232        char *i;
    3333       
    34         /* protocol://                                                  */
     34        memset( url, 0, sizeof( url_t ) );
     35        memset( s, 0, sizeof( s ) );
     36       
     37        /* protocol:// */
    3538        if( ( i = strstr( set_url, "://" ) ) == NULL )
    3639        {
     
    4952                        url->proto = PROTO_SOCKS5;
    5053                else
    51                 {
    52                         return( 0 );
    53                 }
     54                        return 0;
     55               
    5456                strncpy( s, i + 3, MAX_STRING );
    5557        }
    5658       
    57         /* Split                                                        */
     59        /* Split */
    5860        if( ( i = strchr( s, '/' ) ) == NULL )
    5961        {
     
    6769        strncpy( url->host, s, MAX_STRING );
    6870       
    69         /* Check for username in host field                             */
     71        /* Check for username in host field */
    7072        if( strrchr( url->host, '@' ) != NULL )
    7173        {
     
    7678                *url->pass = 0;
    7779        }
    78         /* If not: Fill in defaults                                     */
     80        /* If not: Fill in defaults */
    7981        else
    8082        {
     
    8284        }
    8385       
    84         /* Password?                                                    */
     86        /* Password? */
    8587        if( ( i = strchr( url->user, ':' ) ) != NULL )
    8688        {
     
    8890                strcpy( url->pass, i + 1 );
    8991        }
    90         /* Port number?                                                 */
     92        /* Port number? */
    9193        if( ( i = strchr( url->host, ':' ) ) != NULL )
    9294        {
  • lib/url.h

    r0db75ad rdd34575  
    2626#include "bitlbee.h"
    2727
    28 #define PROTO_HTTP              2
    29 #define PROTO_HTTPS             5
    30 #define PROTO_SOCKS4    3
    31 #define PROTO_SOCKS5    4
    32 #define PROTO_DEFAULT   PROTO_HTTP
     28#define PROTO_HTTP      2
     29#define PROTO_HTTPS     5
     30#define PROTO_SOCKS4    3
     31#define PROTO_SOCKS5    4
     32#define PROTO_DEFAULT   PROTO_HTTP
    3333
    3434typedef struct url
     
    3636        int proto;
    3737        int port;
    38         char host[MAX_STRING];
    39         char file[MAX_STRING];
    40         char user[MAX_STRING];
    41         char pass[MAX_STRING];
     38        char host[MAX_STRING+1];
     39        char file[MAX_STRING+1];
     40        char user[MAX_STRING+1];
     41        char pass[MAX_STRING+1];
    4242} url_t;
    4343
  • lib/xmltree.c

    r0db75ad rdd34575  
    111111};
    112112
    113 struct xt_parser *xt_new( gpointer data )
     113struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data )
    114114{
    115115        struct xt_parser *xt = g_new0( struct xt_parser, 1 );
    116116       
    117117        xt->data = data;
     118        xt->handlers = handlers;
    118119        xt_reset( xt );
    119120       
  • lib/xmltree.h

    r0db75ad rdd34575  
    7171        struct xt_node *cur;
    7272       
    73         struct xt_handler_entry *handlers;
     73        const struct xt_handler_entry *handlers;
    7474        gpointer data;
    7575       
     
    7777};
    7878
    79 struct xt_parser *xt_new( gpointer data );
     79struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data );
    8080void xt_reset( struct xt_parser *xt );
    8181int xt_feed( struct xt_parser *xt, char *text, int text_len );
  • protocols/jabber/Makefile

    r0db75ad rdd34575  
    1010
    1111# [SH] Program variables
    12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o
     12objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o
    1313
    1414CFLAGS += -Wall
  • protocols/jabber/io.c

    r0db75ad rdd34575  
    241241        }
    242242       
    243         /* EAGAIN/etc or a successful read. */
    244         return TRUE;
     243        if( ssl_pending( jd->ssl ) )
     244                /* OpenSSL empties the TCP buffers completely but may keep some
     245                   data in its internap buffers. select() won't see that, but
     246                   ssl_pending() does. */
     247                return jabber_read_callback( data, fd, cond );
     248        else
     249                return TRUE;
    245250}
    246251
     
    521526           from the server too. */
    522527        xt_free( jd->xt );      /* In case we're RE-starting. */
    523         jd->xt = xt_new( ic );
    524         jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers;
     528        jd->xt = xt_new( jabber_handlers, ic );
    525529       
    526530        if( jd->r_inpa <= 0 )
  • protocols/jabber/jabber.c

    r0db75ad rdd34575  
    267267        xt_free( jd->xt );
    268268       
     269        g_free( jd->cached_id_prefix );
    269270        g_free( jd->away_message );
    270271        g_free( jd->username );
  • protocols/msn/ns.c

    r0db75ad rdd34575  
    3434static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
    3535
    36 static void msn_auth_got_passport_id( struct passport_reply *rep );
     36static void msn_auth_got_passport_token( struct msn_auth_data *mad );
    3737
    3838gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
     
    214214                {
    215215                        /* Time for some Passport black magic... */
    216                         if( !passport_get_id( msn_auth_got_passport_id, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
     216                        if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
    217217                        {
    218218                                imcb_error( ic, "Error while contacting Passport server" );
     
    674674}
    675675
    676 static void msn_auth_got_passport_id( struct passport_reply *rep )
     676static void msn_auth_got_passport_token( struct msn_auth_data *mad )
    677677{
    678         struct im_connection *ic = rep->data;
    679         struct msn_data *md = ic->proto_data;
    680         char *key = rep->result;
    681         char buf[1024];
    682        
    683         if( key == NULL )
    684         {
    685                 imcb_error( ic, "Error during Passport authentication (%s)",
    686                                rep->error_string ? rep->error_string : "Unknown error" );
     678        struct im_connection *ic = mad->data;
     679        struct msn_data *md;
     680       
     681        /* Dead connection? */
     682        if( g_slist_find( msn_connections, ic ) == NULL )
     683                return;
     684       
     685        md = ic->proto_data;
     686        if( mad->token )
     687        {
     688                char buf[1024];
     689               
     690                g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token );
     691                msn_write( ic, buf, strlen( buf ) );
     692        }
     693        else
     694        {
     695                imcb_error( ic, "Error during Passport authentication: %s", mad->error );
    687696                imc_logout( ic, TRUE );
    688697        }
    689         else
    690         {
    691                 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );
    692                 msn_write( ic, buf, strlen( buf ) );
    693         }
    694698}
  • protocols/msn/passport.c

    r0db75ad rdd34575  
    1 /* passport.c
     1/** passport.c
    22 *
    3  * Functions to login to microsoft passport service for Messenger
    4  * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>
    5  * Copyright (C) 2004 Wilmer van der Gaast <wilmer@gaast.net>
     3 * Functions to login to Microsoft Passport service for Messenger
     4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net>
    65 *
    76 * This program is free software; you can redistribute it and/or modify             
     
    2423#include "msn.h"
    2524#include "bitlbee.h"
     25#include "url.h"
     26#include "misc.h"
     27#include "xmltree.h"
    2628#include <ctype.h>
    2729#include <errno.h>
    2830
    29 #define MSN_BUF_LEN 8192
     31static int passport_get_token_real( struct msn_auth_data *mad );
     32static void passport_get_token_ready( struct http_request *req );
    3033
    31 static char *prd_cached = NULL;
    32 
    33 static int passport_get_id_real( gpointer func, gpointer data, char *header );
    34 static void passport_get_id_ready( struct http_request *req );
    35 
    36 static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header );
    37 static void passport_retrieve_dalogin_ready( struct http_request *req );
    38 
    39 static char *passport_create_header( char *cookie, char *email, char *pwd );
    40 static void destroy_reply( struct passport_reply *rep );
    41 
    42 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie )
     34int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie )
    4335{
    44         char *header = passport_create_header( cookie, username, password );
     36        struct msn_auth_data *mad = g_new0( struct msn_auth_data, 1 );
     37        int i;
    4538       
    46         if( prd_cached == NULL )
    47                 return passport_retrieve_dalogin( func, data, header );
    48         else
    49                 return passport_get_id_real( func, data, header );
     39        mad->username = g_strdup( username );
     40        mad->password = g_strdup( password );
     41        mad->cookie = g_strdup( cookie );
     42       
     43        mad->callback = func;
     44        mad->data = data;
     45       
     46        mad->url = g_strdup( SOAP_AUTHENTICATION_URL );
     47        mad->ttl = 3; /* Max. # of redirects. */
     48       
     49        /* HTTP-escape stuff and s/,/&/ */
     50        http_decode( mad->cookie );
     51        for( i = 0; mad->cookie[i]; i ++ )
     52                if( mad->cookie[i] == ',' )
     53                        mad->cookie[i] = '&';
     54       
     55        /* Microsoft doesn't allow password longer than 16 chars and silently
     56           fails authentication if you give the "full version" of your passwd. */
     57        if( strlen( mad->password ) > MAX_PASSPORT_PWLEN )
     58                mad->password[MAX_PASSPORT_PWLEN] = 0;
     59       
     60        return passport_get_token_real( mad );
    5061}
    5162
    52 static int passport_get_id_real( gpointer func, gpointer data, char *header )
     63static int passport_get_token_real( struct msn_auth_data *mad )
    5364{
    54         struct passport_reply *rep;
    55         char *server, *dummy, *reqs;
     65        char *post_payload, *post_request;
    5666        struct http_request *req;
     67        url_t url;
    5768       
    58         rep = g_new0( struct passport_reply, 1 );
    59         rep->data = data;
    60         rep->func = func;
    61         rep->header = header;
     69        url_set( &url, mad->url );
    6270       
    63         server = g_strdup( prd_cached );
    64         dummy = strchr( server, '/' );
     71        post_payload = g_markup_printf_escaped( SOAP_AUTHENTICATION_PAYLOAD,
     72                                                mad->username,
     73                                                mad->password,
     74                                                mad->cookie );
    6575       
    66         if( dummy == NULL )
    67         {
    68                 destroy_reply( rep );
    69                 return( 0 );
    70         }
     76        post_request = g_strdup_printf( SOAP_AUTHENTICATION_REQUEST,
     77                                        url.file, url.host,
     78                                        (int) strlen( post_payload ),
     79                                        post_payload );
     80                                       
     81        req = http_dorequest( url.host, url.port, 1, post_request,
     82                              passport_get_token_ready, mad );
    7183       
    72         reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
     84        g_free( post_request );
     85        g_free( post_payload );
    7386       
    74         *dummy = 0;
    75         req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep );
    76        
    77         g_free( server );
    78         g_free( reqs );
    79        
    80         if( req == NULL )
    81                 destroy_reply( rep );
    82        
    83         return( req != NULL );
     87        return req != NULL;
    8488}
    8589
    86 static void passport_get_id_ready( struct http_request *req )
     90static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data );
     91static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data );
     92
     93static const struct xt_handler_entry passport_xt_handlers[] = {
     94        { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", passport_xt_extract_token },
     95        { "S:Fault",                  "S:Envelope",                 passport_xt_handle_fault  },
     96        { NULL,                       NULL,                         NULL                      }
     97};
     98
     99static void passport_get_token_ready( struct http_request *req )
    87100{
    88         struct passport_reply *rep = req->data;
     101        struct msn_auth_data *mad = req->data;
     102        struct xt_parser *parser;
    89103       
    90         if( !g_slist_find( msn_connections, rep->data ) )
     104        g_free( mad->url );
     105        g_free( mad->error );
     106        mad->url = mad->error = NULL;
     107       
     108        if( req->status_code == 200 )
    91109        {
    92                 destroy_reply( rep );
    93                 return;
    94         }
    95        
    96         if( req->finished && req->reply_headers && req->status_code == 200 )
    97         {
    98                 char *dummy;
    99                
    100                 if( ( dummy = strstr( req->reply_headers, "from-PP='" ) ) )
    101                 {
    102                         char *responseend;
    103                        
    104                         dummy += strlen( "from-PP='" );
    105                         responseend = strchr( dummy, '\'' );
    106                         if( responseend )
    107                                 *responseend = 0;
    108                        
    109                         rep->result = g_strdup( dummy );
    110                 }
    111                 else
    112                 {
    113                         rep->error_string = g_strdup( "Could not parse Passport server response" );
    114                 }
     110                parser = xt_new( passport_xt_handlers, mad );
     111                xt_feed( parser, req->reply_body, req->body_size );
     112                xt_handle( parser, NULL, -1 );
     113                xt_free( parser );
    115114        }
    116115        else
    117116        {
    118                 rep->error_string = g_strdup_printf( "HTTP error: %s",
    119                                       req->status_string ? req->status_string : "Unknown error" );
     117                mad->error = g_strdup_printf( "HTTP error %d (%s)", req->status_code,
     118                                              req->status_string ? req->status_string : "unknown" );
    120119        }
    121120       
    122         rep->func( rep );
    123         destroy_reply( rep );
     121        if( mad->error == NULL && mad->token == NULL )
     122                mad->error = g_strdup( "Could not parse Passport server response" );
     123       
     124        if( mad->url && mad->token == NULL )
     125        {
     126                passport_get_token_real( mad );
     127        }
     128        else
     129        {
     130                mad->callback( mad );
     131               
     132                g_free( mad->url );
     133                g_free( mad->username );
     134                g_free( mad->password );
     135                g_free( mad->cookie );
     136                g_free( mad->token );
     137                g_free( mad->error );
     138                g_free( mad );
     139        }
    124140}
    125141
    126 static char *passport_create_header( char *cookie, char *email, char *pwd )
     142static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data )
    127143{
    128         char *buffer;
    129         char *currenttoken;
    130         char *email_enc, *pwd_enc;
     144        struct msn_auth_data *mad = data;
     145        char *s;
    131146       
    132         currenttoken = strstr( cookie, "lc=" );
    133         if( currenttoken == NULL )
    134                 return NULL;
     147        if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 )
     148                mad->token = g_memdup( node->text, node->text_len + 1 );
    135149       
    136         email_enc = g_new0( char, strlen( email ) * 3 + 1 );
    137         strcpy( email_enc, email );
    138         http_encode( email_enc );
    139        
    140         pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 );
    141         strcpy( pwd_enc, pwd );
    142         http_encode( pwd_enc );
    143        
    144         buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET,"
    145                                   "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
    146                                   "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
    147                                   currenttoken );
    148        
    149         g_free( email_enc );
    150         g_free( pwd_enc );
    151        
    152         return buffer;
     150        return XT_HANDLED;
    153151}
    154152
    155 static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
     153static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data )
    156154{
    157         struct passport_reply *rep = g_new0( struct passport_reply, 1 );
    158         struct http_request *req;
     155        struct msn_auth_data *mad = data;
     156        struct xt_node *code = xt_find_node( node->children, "faultcode" );
     157        struct xt_node *string = xt_find_node( node->children, "faultstring" );
     158        struct xt_node *redirect = xt_find_node( node->children, "psf:redirectUrl" );
    159159       
    160         rep->data = data;
    161         rep->func = func;
    162         rep->header = header;
     160        if( redirect && redirect->text_len && mad->ttl-- > 0 )
     161                mad->url = g_memdup( redirect->text, redirect->text_len + 1 );
    163162       
    164         req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep );
     163        if( code == NULL || code->text_len == 0 )
     164                mad->error = g_strdup( "Unknown error" );
     165        else
     166                mad->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ?
     167                                              string->text : "no description available" );
    165168       
    166         if( !req )
    167                 destroy_reply( rep );
    168        
    169         return( req != NULL );
     169        return XT_HANDLED;
    170170}
    171 
    172 static void passport_retrieve_dalogin_ready( struct http_request *req )
    173 {
    174         struct passport_reply *rep = req->data;
    175         char *dalogin;
    176         char *urlend;
    177        
    178         if( !g_slist_find( msn_connections, rep->data ) )
    179         {
    180                 destroy_reply( rep );
    181                 return;
    182         }
    183        
    184         if( !req->finished || !req->reply_headers || req->status_code != 200 )
    185         {
    186                 rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",
    187                                         req->status_string ? req->status_string : "Unknown error" );
    188                 goto failure;
    189         }
    190        
    191         dalogin = strstr( req->reply_headers, "DALogin=" );     
    192        
    193         if( !dalogin )
    194         {
    195                 rep->error_string = g_strdup( "Parse error while fetching DALogin" );
    196                 goto failure;
    197         }
    198        
    199         dalogin += strlen( "DALogin=" );
    200         urlend = strchr( dalogin, ',' );
    201         if( urlend )
    202                 *urlend = 0;
    203        
    204         /* strip the http(s):// part from the url */
    205         urlend = strstr( urlend, "://" );
    206         if( urlend )
    207                 dalogin = urlend + strlen( "://" );
    208        
    209         if( prd_cached == NULL )
    210                 prd_cached = g_strdup( dalogin );
    211        
    212         if( passport_get_id_real( rep->func, rep->data, rep->header ) )
    213         {
    214                 rep->header = NULL;
    215                 destroy_reply( rep );
    216                 return;
    217         }
    218        
    219 failure:       
    220         rep->func( rep );
    221         destroy_reply( rep );
    222 }
    223 
    224 static void destroy_reply( struct passport_reply *rep )
    225 {
    226         g_free( rep->result );
    227         g_free( rep->header );
    228         g_free( rep->error_string );
    229         g_free( rep );
    230 }
  • protocols/msn/passport.h

    r0db75ad rdd34575  
    1 #ifndef __PASSPORT_H__
    2 #define __PASSPORT_H__
    31/* passport.h
    42 *
    5  * Functions to login to Microsoft Passport Service for Messenger
    6  * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>,
    7  *                    Wilmer van der Gaast <wilmer@gaast.net>
     3 * Functions to login to Microsoft Passport service for Messenger
     4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net>
    85 *
    96 * This program is free software; you can redistribute it and/or modify             
     
    1815 * You should have received a copy of the GNU General Public License               
    1916 * along with this program; if not, write to the Free Software                     
    20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA         
     17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA         
    2118 */
     19
     20/* Thanks to http://msnpiki.msnfanatic.com/index.php/MSNP13:SOAPTweener
     21   for the specs! */
     22
     23#ifndef __PASSPORT_H__
     24#define __PASSPORT_H__
    2225
    2326#include <stdio.h>
     
    3336#include "nogaim.h"
    3437
    35 struct passport_reply
     38#define MAX_PASSPORT_PWLEN 16
     39
     40struct msn_auth_data
    3641{
    37         void (*func)( struct passport_reply * );
    38         void *data;
    39         char *result;
    40         char *header;
    41         char *error_string;
     42        char *url;
     43        int ttl;
     44       
     45        char *username;
     46        char *password;
     47        char *cookie;
     48       
     49        /* The end result, the only thing we'll really be interested in
     50           once finished. */
     51        char *token;
     52        char *error; /* Yeah, or that... */
     53       
     54        void (*callback)( struct msn_auth_data *mad );
     55        gpointer data;
    4256};
    4357
    44 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie );
     58#define SOAP_AUTHENTICATION_URL "https://loginnet.passport.com/RST.srf"
     59
     60#define SOAP_AUTHENTICATION_REQUEST \
     61"POST %s HTTP/1.0\r\n" \
     62"Accept: text/*\r\n" \
     63"User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \
     64"Host: %s\r\n" \
     65"Content-Length: %d\r\n" \
     66"Cache-Control: no-cache\r\n" \
     67"\r\n" \
     68"%s"
     69
     70#define SOAP_AUTHENTICATION_PAYLOAD \
     71"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
     72"<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \
     73  "<Header>" \
     74    "<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">" \
     75      "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \
     76      "<ps:BinaryVersion>4</ps:BinaryVersion>" \
     77      "<ps:UIVersion>1</ps:UIVersion>" \
     78      "<ps:Cookies></ps:Cookies>" \
     79      "<ps:RequestParams>AQAAAAIAAABsYwQAAAAzMDg0</ps:RequestParams>" \
     80    "</ps:AuthInfo>" \
     81    "<wsse:Security>" \
     82       "<wsse:UsernameToken Id=\"user\">" \
     83         "<wsse:Username>%s</wsse:Username>" \
     84         "<wsse:Password>%s</wsse:Password>" \
     85       "</wsse:UsernameToken>" \
     86    "</wsse:Security>" \
     87  "</Header>" \
     88  "<Body>" \
     89    "<ps:RequestMultipleSecurityTokens xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"RSTS\">" \
     90      "<wst:RequestSecurityToken Id=\"RST0\">" \
     91        "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
     92        "<wsp:AppliesTo>" \
     93          "<wsa:EndpointReference>" \
     94            "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \
     95          "</wsa:EndpointReference>" \
     96        "</wsp:AppliesTo>" \
     97      "</wst:RequestSecurityToken>" \
     98      "<wst:RequestSecurityToken Id=\"RST1\">" \
     99       "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \
     100        "<wsp:AppliesTo>" \
     101          "<wsa:EndpointReference>" \
     102            "<wsa:Address>messenger.msn.com</wsa:Address>" \
     103          "</wsa:EndpointReference>" \
     104        "</wsp:AppliesTo>" \
     105        "<wsse:PolicyReference URI=\"?%s\"></wsse:PolicyReference>" \
     106      "</wst:RequestSecurityToken>" \
     107    "</ps:RequestMultipleSecurityTokens>" \
     108  "</Body>" \
     109"</Envelope>"
     110
     111int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie );
    45112
    46113#endif /* __PASSPORT_H__ */
  • protocols/yahoo/libyahoo2.c

    r0db75ad rdd34575  
    737737
    738738        memcpy(data + pos, "YMSG", 4); pos += 4;
    739         pos += yahoo_put16(data + pos, 0x0a00);
     739        pos += yahoo_put16(data + pos, 0x000c);
    740740        pos += yahoo_put16(data + pos, 0x0000);
    741741        pos += yahoo_put16(data + pos, pktlen + extra_pad);
     
    33513351                                        break;
    33523352                                case 5:
    3353                                         if(cp != "\005")
     3353                                        if(strcmp(cp, "5") != 0)
    33543354                                                yct->location = cp;
    33553355                                        k = 0;
  • protocols/yahoo/yahoo.c

    r0db75ad rdd34575  
    315315        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
    316316       
    317         yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
     317        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
    318318}
    319319
  • query.c

    r0db75ad rdd34575  
    140140        if( ans )
    141141        {
    142                 imcb_log( q->ic, "Accepted: %s", q->question );
     142                if( q->ic )
     143                        imcb_log( q->ic, "Accepted: %s", q->question );
     144                else
     145                        irc_usermsg( irc, "Accepted: %s", q->question );
    143146                q->yes( NULL, q->data );
    144147        }
    145148        else
    146149        {
    147                 imcb_log( q->ic, "Rejected: %s", q->question );
     150                if( q->ic )
     151                        imcb_log( q->ic, "Rejected: %s", q->question );
     152                else
     153                        irc_usermsg( irc, "Rejected: %s", q->question );
    148154                q->no( NULL, q->data );
    149155        }
  • root_commands.c

    r0db75ad rdd34575  
    204204}
    205205
     206void cmd_account_del_yes( gpointer w, void *data )
     207{
     208        account_t *a = data;
     209        irc_t *irc = a->irc;
     210       
     211        if( a->ic )
     212        {
     213                irc_usermsg( irc, "Account is still logged in, can't delete" );
     214        }
     215        else
     216        {
     217                account_del( irc, a );
     218                irc_usermsg( irc, "Account deleted" );
     219        }
     220}
     221
     222void cmd_account_del_no( gpointer w, void *data )
     223{
     224}
     225
    206226static void cmd_account( irc_t *irc, char **cmd )
    207227{
     
    258278                else
    259279                {
    260                         account_del( irc, a );
    261                         irc_usermsg( irc, "Account deleted" );
     280                        char *msg;
     281                       
     282                        msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will "
     283                                               "also forget all your saved nicknames. If you want "
     284                                               "to change your username/password, use the `account "
     285                                               "set' command. Are you sure you want to delete this "
     286                                               "account?", a->prpl->name, a->user );
     287                        query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, a );
     288                        g_free( msg );
    262289                }
    263290        }
     
    769796                else
    770797                        irc_usermsg( irc, "%s is empty", set_name );
     798
     799                if( strchr( set_name, '/' ) )
     800                        irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." );
    771801        }
    772802        else
  • set.c

    r0db75ad rdd34575  
    230230        return value;
    231231}
    232 
    233 char *set_eval_charset( set_t *set, char *value )
    234 {
    235         GIConv cd;
    236 
    237         if ( g_strncasecmp( value, "none", 4 ) == 0 )
    238                 return value;
    239 
    240         cd = g_iconv_open( "UTF-8", value );
    241         if( cd == (GIConv) -1 )
    242                 return NULL;
    243 
    244         g_iconv_close( cd );
    245         return value;
    246 }
  • set.h

    r0db75ad rdd34575  
    9797char *set_eval_to_char( set_t *set, char *value );
    9898char *set_eval_ops( set_t *set, char *value );
    99 char *set_eval_charset( set_t *set, char *value );
    10099
    101100#endif /* __SET_H__ */
  • storage_xml.c

    r0db75ad rdd34575  
    8080                char *nick = xml_attr( attr_names, attr_values, "nick" );
    8181                char *pass = xml_attr( attr_names, attr_values, "password" );
    82                 md5_byte_t *pass_dec = NULL;
     82                int st;
    8383               
    8484                if( !nick || !pass )
     
    8787                                     "Missing attributes for %s element", element_name );
    8888                }
    89                 else if( base64_decode( pass, &pass_dec ) != 21 )
    90                 {
     89                else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 )
     90                {
     91                        xd->pass_st = XML_PASS_WRONG;
    9192                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
    9293                                     "Error while decoding password attribute" );
    9394                }
     95                else if( st == 0 )
     96                {
     97                        if( xd->pass_st != XML_PASS_CHECK_ONLY )
     98                                xd->pass_st = XML_PASS_OK;
     99                }
    94100                else
    95101                {
    96                         md5_byte_t pass_md5[16];
    97                         md5_state_t md5_state;
    98                         int i;
    99                        
    100                         md5_init( &md5_state );
    101                         md5_append( &md5_state, (md5_byte_t*) xd->given_pass, strlen( xd->given_pass ) );
    102                         md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */
    103                         md5_finish( &md5_state, pass_md5 );
    104                        
    105                         for( i = 0; i < 16; i ++ )
    106                         {
    107                                 if( pass_dec[i] != pass_md5[i] )
    108                                 {
    109                                         xd->pass_st = XML_PASS_WRONG;
    110                                         g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
    111                                                      "Password mismatch" );
    112                                         break;
    113                                 }
    114                         }
    115                        
    116                         /* If we reached the end of the loop, it was a match! */
    117                         if( i == 16 )
    118                         {
    119                                 if( xd->pass_st != XML_PASS_CHECK_ONLY )
    120                                         xd->pass_st = XML_PASS_OK;
    121                         }
    122                 }
    123                
    124                 g_free( pass_dec );
     102                        xd->pass_st = XML_PASS_WRONG;
     103                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
     104                                     "Password mismatch" );
     105                }
    125106        }
    126107        else if( xd->pass_st < XML_PASS_OK )
     
    428409                int pass_len;
    429410               
    430                 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );
     411                pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 );
    431412                pass_b64 = base64_encode( pass_cr, pass_len );
    432413                g_free( pass_cr );
  • tests/check_arc.c

    r0db75ad rdd34575  
    77#include "arc.h"
    88
    9 char *password = "TotT";
     9char *password = "ArcVier";
    1010
    1111char *clear_tests[] =
     
    1414        "ItllBeBitlBee",
    1515        "One more boring password",
     16        "Hoi hoi",
    1617        NULL
    1718};
     
    2829                int len;
    2930               
    30                 len = arc_encode( clear_tests[i], 0, &crypted, password );
     31                len = arc_encode( clear_tests[i], 0, &crypted, password, 12 );
    3132                len = arc_decode( crypted, len, &decrypted, password );
    3233               
     
    4142struct
    4243{
    43         unsigned char crypted[24];
     44        unsigned char crypted[30];
    4445        int len;
    4546        char *decrypted;
    4647} decrypt_tests[] = {
     48        /* One block with padding. */
    4749        {
    4850                {
    49                         0xc3, 0x0d, 0x43, 0xc3, 0xee, 0x80, 0xe2, 0x8c, 0x0b, 0x29, 0x32, 0x7e,
    50                         0x38, 0x05, 0x82, 0x10, 0x21, 0x1c, 0x4a, 0x00, 0x2c
    51                 }, 21, "Debugging sucks"
     51                        0x3f, 0x79, 0xb0, 0xf5, 0x91, 0x56, 0xd2, 0x1b, 0xd1, 0x4b, 0x67, 0xac,
     52                        0xb1, 0x31, 0xc9, 0xdb, 0xf9, 0xaa
     53                }, 18, "short pass"
    5254        },
     55       
     56        /* Two blocks with padding. */
    5357        {
    5458                {
    55                         0xb0, 0x00, 0x57, 0x0d, 0x0d, 0x0d, 0x70, 0xe1, 0xc0, 0x00, 0xa4, 0x25,
    56                         0x7d, 0xbe, 0x03, 0xcc, 0x24, 0xd1, 0x0c
    57                 }, 19, "Testing rocks"
     59                        0xf9, 0xa6, 0xec, 0x5d, 0xc7, 0x06, 0xb8, 0x6b, 0x63, 0x9f, 0x2d, 0xb5,
     60                        0x7d, 0xaa, 0x32, 0xbb, 0xd8, 0x08, 0xfd, 0x81, 0x2e, 0xca, 0xb4, 0xd7,
     61                        0x2f, 0x36, 0x9c, 0xac, 0xa0, 0xbc
     62                }, 30, "longer password"
    5863        },
     64
     65        /* This string is exactly two "blocks" long, to make sure unpadded strings also decrypt
     66           properly. */
    5967        {
    6068                {
    61                         0xb6, 0x92, 0x59, 0xe4, 0xf9, 0xc1, 0x7a, 0xf6, 0xf3, 0x18, 0xea, 0x28,
    62                         0x73, 0x6d, 0xb3, 0x0a, 0x6f, 0x0a, 0x2b, 0x43, 0x57, 0xe9, 0x3e, 0x63
    63                 }, 24, "OSCAR is creepy..."
     69                        0x95, 0x4d, 0xcf, 0x4d, 0x5e, 0x6c, 0xcf, 0xef, 0xb9, 0x80, 0x00, 0xef,
     70                        0x25, 0xe9, 0x17, 0xf6, 0x29, 0x6a, 0x82, 0x79, 0x1c, 0xca, 0x68, 0xb5,
     71                        0x4e, 0xd0, 0xc1, 0x41, 0x8e, 0xe6
     72                }, 30, "OSCAR is really creepy.."
    6473        },
    6574        { "", 0, NULL }
     
    8089               
    8190                fail_if( strcmp( decrypt_tests[i].decrypted, decrypted ) != 0,
    82                          "%s didn't decrypt properly", clear_tests[i] );
     91                         "`%s' didn't decrypt properly", decrypt_tests[i].decrypted );
    8392               
    8493                g_free( decrypted );
  • tests/check_help.c

    r0db75ad rdd34575  
    77#include "help.h"
    88
    9 START_TEST(test_help_none)
     9START_TEST(test_help_initfree)
    1010        help_t *h, *r;
    1111        r = help_init(&h, "/dev/null");
    1212        fail_if(r == NULL);
    1313        fail_if(r != h);
     14       
     15        help_free(&h);
     16        fail_if(h != NULL);
    1417END_TEST
    1518
     
    2528        TCase *tc_core = tcase_create("Core");
    2629        suite_add_tcase (s, tc_core);
    27         tcase_add_test (tc_core, test_help_none);
     30        tcase_add_test (tc_core, test_help_initfree);
    2831        tcase_add_test (tc_core, test_help_nonexistent);
    2932        return s;
  • tests/check_irc.c

    r0db75ad rdd34575  
    3737        irc = irc_new(g_io_channel_unix_get_fd(ch1));
    3838
    39         fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\n"
    40                         "USER a a a a\r\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL);
     39        fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\r\n"
     40                        "USER a a a a\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL);
    4141        fail_unless(g_io_channel_flush(ch2, NULL) == G_IO_STATUS_NORMAL);
    4242
  • tests/check_jabber_sasl.c

    r0db75ad rdd34575  
    1818struct
    1919{
    20         const char *challenge;
     20        char *challenge;
    2121        char *key;
    2222        char *value;
Note: See TracChangeset for help on using the changeset viewer.