Changes in / [b79308b:6cac643]


Ignore:
Files:
2 added
5 deleted
70 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    rb79308b r6cac643  
    5050        $(MAKE) -C tests
    5151
     52lcov:
    5253gcov: check
    5354        gcov *.c
  • account.c

    rb79308b r6cac643  
    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        
    188184        for( a = irc->accounts; a; a = (l=a)->next )
    189185                if( a == acc )
    190186                {
     187                        if( a->ic ) return; /* Caller should have checked, accounts still in use can't be deleted. */
     188                       
    191189                        if( l )
     190                        {
    192191                                l->next = a->next;
     192                        }
    193193                        else
     194                        {
    194195                                irc->accounts = a->next;
     196                        }
    195197                       
    196198                        while( a->set )
     
    201203                        g_free( a->user );
    202204                        g_free( a->pass );
    203                         g_free( a->server );
     205                        if( a->server ) g_free( a->server );
    204206                        if( a->reconnect )      /* This prevents any reconnect still queued to happen */
    205207                                cancel_auto_reconnect( a );
  • bitlbee.c

    rb79308b r6cac643  
    226226        if( st == size )
    227227        {
     228                g_free( irc->sendbuffer );
     229                irc->sendbuffer = NULL;
     230                irc->w_watch_source_id = 0;
     231               
    228232                if( irc->status & USTATUS_SHUTDOWN )
    229                 {
    230233                        irc_free( irc );
    231                 }
    232                 else
    233                 {
    234                         g_free( irc->sendbuffer );
    235                         irc->sendbuffer = NULL;
    236                         irc->w_watch_source_id = 0;
    237                 }
    238234               
    239235                return FALSE;
  • bitlbee.conf

    rb79308b r6cac643  
    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).
    5451##
    5552# AuthPassword = ItllBeBitlBee   ## Heh.. Our slogan. ;-)
    56 ## or
    57 # AuthPassword = md5:gzkK0Ox/1xh+1XTsQjXxBJ571Vgl
    5853
    5954## OperPassword
     
    6257##
    6358# OperPassword = ChangeMe!
    64 ## or
    65 # OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX
    6659
    6760## HostName
  • bitlbee.h

    rb79308b r6cac643  
    3030
    3131#define PACKAGE "BitlBee"
    32 #define BITLBEE_VERSION "1.2"
     32#define BITLBEE_VERSION "1.1.1dev"
    3333#define VERSION BITLBEE_VERSION
    3434
    35 #define MAX_STRING 511
     35#define MAX_STRING 128
    3636
    3737#if HAVE_CONFIG_H
     
    160160gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond );
    161161
    162 char *set_eval_root_nick( set_t *set, char *new_nick );
    163 
    164162extern global_t global;
    165163
  • conf.c

    rb79308b r6cac643  
    253253                        {
    254254                                g_strfreev( conf->migrate_storage );
    255                                 conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 );
     255                                conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
    256256                        }
    257257                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
  • debian/README.Debian

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

    rb79308b r6cac643  
    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
    92#
    103# Init script for BitlBee Debian package. Based on skeleton init script:
     
    2518# Default value
    2619BITLBEE_PORT=6667
    27 BITLBEE_OPTS=-F
     20DAEMON_OPT=-F
    2821
    2922# Read config file if it is present.
     
    4437       
    4538        start-stop-daemon --start --quiet --pidfile $PIDFILE \
    46                 -c bitlbee: \
    47                 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS
     39                -c bitlbee -g nogroup \
     40                --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $DAEMON_OPT
    4841}
    4942
  • debian/changelog

    rb79308b r6cac643  
    1 bitlbee (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 
    10 bitlbee (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 
    18 bitlbee (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 
    29 bitlbee (1.2-1) unstable; urgency=low
    30 
    31   * New upstream release. (Closes: #325017, #386914, #437515)
    32   * With hopefully completely sane charset handling (Closes: #296145)
     1bitlbee (1.1.1dev-0pre) unstable; urgency=low
     2
    333  * Switched to the new forking daemon mode. Added /etc/default/bitlbee
    344    file, an init script. People who want to stick with inetd can do so, see
    355    the defaults file.
    36     (Closes: #460741, #466171, #294585, #345038, #306452, #392682)
    376  * Got rid of debconf Woody compatibility stuff.
    387  * No more MPL code in BitlBee, thanks to the Jabber module rewrite!
    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 
    45 bitlbee (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 
    52 bitlbee (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
     8
     9 -- Wilmer van der Gaast <wilmer@gaast.net>  Fri, 06 Jul 2007 09:09:36 +0100
    5910
    6011bitlbee (1.0.3-1.3) unstable; urgency=low
  • debian/conffiles

    rb79308b r6cac643  
    11/etc/bitlbee/motd.txt
    22/etc/bitlbee/bitlbee.conf
    3 /etc/init.d/bitlbee
  • debian/control

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

    rb79308b r6cac643  
    1414BITLBEE_DISABLED=0
    1515BITLBEE_UPGRADE_DONT_RESTART=0
    16 [ -r /etc/default/bitlbee ] && . /etc/default/bitlbee
     16[ -r /etc/default/bitlbee ] && source /etc/default/bitlbee
    1717
    18 if [ "$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.
     18if [ "$BITLBEE_DISABLED" = "0" ]; then
     19        ## In case it's still there (if we're upgrading right now)
    2220        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
    3021fi
    3122
     
    7465fi
    7566
    76 adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee
     67adduser --system --home /var/lib/bitlbee/ --disabled-login --disabled-password bitlbee
    7768chmod 700 /var/lib/bitlbee/
    7869
    7970## Can't do this in packaging phase: Don't know the UID yet. Access to
    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.
    84 if getent group bitlbee > /dev/null; then
    85         chmod 640 /etc/bitlbee/bitlbee.conf
    86         chown root:bitlbee /etc/bitlbee/bitlbee.conf
    87 else
    88         chmod 600 /etc/bitlbee/bitlbee.conf
    89         chown bitlbee /etc/bitlbee/bitlbee.conf
    90 fi
     71## the file should be limited, now that it stores passwords.
     72chmod 600 /etc/bitlbee/bitlbee.conf
     73chown bitlbee /etc/bitlbee/bitlbee.conf
    9174
    9275if [ -z "$2" ]; then
  • debian/postrm

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

    rb79308b r6cac643  
    33DEBUG ?= 0
    44
    5 ifdef BITLBEE_VERSION
    6 BITLBEE_FORCE_VERSION=1
    7 else
    85# Want to use the full package version number instead of just the release.
    96BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')"
    107export BITLBEE_VERSION
    11 endif
     8
    129
    1310build-arch: build-arch-stamp
    1411build-arch-stamp:
    1512        if [ ! -d debian ]; then exit 1; fi
    16         ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent
     13        ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee $(DEB_BUILD_OPTIONS)
    1714        $(MAKE)
    1815#       $(MAKE) -C doc/ all
     
    6966                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
    7067        dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee
    71 ifdef BITLBEE_FORCE_VERSION
     68ifdef BITLBEE_VERSION
    7269        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'
    7370else
  • doc/CHANGES

    rb79308b r6cac643  
    1 Version 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 
    13 Finished ...
    14 
    151Version 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.
    165- Added ForkDaemon mode next to the existing Daemon- and inetd modes. With
    176  ForkDaemon you can run BitlBee as a stand-alone daemon and every connection
     
    3221  1.x is so old that supporting it really isn't necessary anymore.
    3322- Many, many, MANY little changes, improvements, fixes. Using non-blocking
    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.
     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.
    4626- Most important change: New file format for user data (accounts, nicks and
    4727  settings). Migration to the new format should happen transparently,
     
    8969  * An XML console (add xmlconsole to your contact list or see "help set
    9070    xmlconsole" if you want it permanently).
    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 
    97 Finished 17 Mar 2008
     71
     72Finished ???
    9873
    9974Version 1.0.4:
  • doc/README

    rb79308b r6cac643  
    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 
    46 If you don't want to run any inetd daemon, you can run BitlBee in Daemon
    47 mode. Right now, daemon mode may be a bad idea on servers with multiple
    48 users, since possible fatal BitlBee bugs will crash the BitlBee process and
    49 disconnect all connected users at once. Instead, you can use ForkDaemon
    50 mode, which serves every user from a separate process, without depending on
    51 an inetd daemon.
    52 
    53 To use BitlBee in daemon mode, just start it with the right flags or enable
    54 it in bitlbee.conf. You probably want to write an init script to start
    55 BitlBee automatically after a reboot. (This is where you realise using
    56 a package from your distro would've been a better idea. :-P)
    5743
    5844
  • doc/user-guide/Support.xml

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

    rb79308b r6cac643  
    163163
    164164                        <para>
    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.
     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.
    166170                        </para>
    167171                </description>
     
    379383
    380384        <bitlbee-setting name="charset" type="string" scope="global">
    381                 <default>utf-8</default>
     385                <default>iso8859-1</default>
    382386                <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values>
    383387
    384388                <description>
    385389                        <para>
    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
     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
    391395                        </para>
    392396                </description>
     
    589593        </bitlbee-setting>
    590594
    591         <bitlbee-setting name="root_nick" type="string" scope="global">
    592                 <default>root</default>
    593 
    594                 <description>
    595                         <para>
    596                                 Normally the "bot" that takes all your BitlBee commands is called "root". If you don't like this name, you can rename it to anything else using the <emphasis>rename</emphasis> command, or by changing this setting.
    597                         </para>
    598                 </description>
    599         </bitlbee-setting>
    600 
    601595        <bitlbee-setting name="save_on_quit" type="boolean" scope="global">
    602596                <default>true</default>
     
    683677                <description>
    684678                        <para>
    685                                 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.
     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. ;-)
    686680                        </para>
    687681                </description>
     
    836830                <short-description>Change friendly name, nick</short-description>
    837831                <syntax>nick &lt;connection&gt; [&lt;new nick&gt;]</syntax>
    838                 <syntax>nick &lt;connection&gt;</syntax>
    839 
    840                 <description>
    841                         <para>
    842                                 Deprecated: Use the per-account <emphasis>display_name</emphasis> setting to read and change this information.
     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.
    843841                        </para>
    844842                </description>
    845843
    846844                <ircexample>
    847                         <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline>
    848                         <ircline nick="root">display_name = `The majestik møøse'</ircline>
     845                        <ircline nick="wouter">nick 1 "Wouter Paesen"</ircline>
     846                        <ircline nick="root">Setting your name on connection 1 to `Wouter Paesen'</ircline>
    849847                </ircexample>
    850848
  • doc/user-guide/misc.xml

    rb79308b r6cac643  
    4747</variablelist>
    4848
     49<para>
     50This 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
    4953</sect1>
    5054
     
    5256<title>Groupchats</title>
    5357<para>
    54 BitlBee now supports groupchats on all IM networks. This text will try to explain you how they work.
     58Since version 0.8x, BitlBee supports groupchats on the MSN and Yahoo! networks. This text will try to explain you how they work.
    5559</para>
    5660
     
    6973
    7074<para>
    71 If 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.
     75If 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.
    7276</para>
    7377
     
    7882<para>
    7983Some 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>
     87This 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>
     96Obviously 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>
     100Please 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.
    80101</para>
    81102
     
    100121        <member>On the phone, Phone, On phone</member>
    101122        <member>Out to lunch, Lunch, Food</member>
    102         <member>Invisible, Hidden</member>
    103123</simplelist>
    104124
     
    108128
    109129<para>
    110 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. Most IM-protocols can also show this additional information to your buddies.
     130You 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.
    111131</para>
    112132
  • doc/user-guide/quickstart.xml

    rb79308b r6cac643  
    6161
    6262<para>
    63 Now BitlBee logs in and downloads the contact list from the IM server. In a few seconds, all your on-line buddies should show up in the control channel.
     63For 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.
    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 Note 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>
    137 If 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>.
     133If 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).
    138134</para>
    139135
  • ipc.c

    rb79308b r6cac643  
    258258        else
    259259        {
    260                 ipc_master_free_fd( source );
     260                GSList *l;
     261                struct bitlbee_child *c;
     262               
     263                for( l = child_list; l; l = l->next )
     264                {
     265                        c = l->data;
     266                        if( c->ipc_fd == source )
     267                        {
     268                                ipc_master_free_one( c );
     269                                child_list = g_slist_remove( child_list, c );
     270                                break;
     271                        }
     272                }
    261273        }
    262274       
     
    276288        else
    277289        {
    278                 ipc_child_disable();
     290                b_event_remove( global.listen_watch_source_id );
     291                close( global.listen_socket );
     292               
     293                global.listen_socket = -1;
    279294        }
    280295       
     
    311326        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    312327        {
    313                 if( global.listen_socket >= 0 )
    314                         if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 )
    315                                 ipc_child_disable();
     328                write( global.listen_socket, msg_buf, strlen( msg_buf ) );
    316329        }
    317330        else if( global.conf->runmode == RUNMODE_DAEMON )
     
    363376        {
    364377                int msg_len = strlen( msg_buf );
    365                 GSList *l, *next;
    366                
    367                 for( l = child_list; l; l = next )
     378                GSList *l;
     379               
     380                for( l = child_list; l; l = l->next )
    368381                {
    369382                        struct bitlbee_child *c = l->data;
    370                        
    371                         next = l->next;
    372                         if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 )
    373                         {
    374                                 ipc_master_free_one( c );
    375                                 child_list = g_slist_remove( child_list, c );
    376                         }
     383                        write( c->ipc_fd, msg_buf, msg_len );
    377384                }
    378385        }
     
    403410}
    404411
    405 void 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 
    422412void ipc_master_free_all()
    423413{
     
    429419        g_slist_free( child_list );
    430420        child_list = NULL;
    431 }
    432 
    433 void ipc_child_disable()
    434 {
    435         b_event_remove( global.listen_watch_source_id );
    436         close( global.listen_socket );
    437        
    438         global.listen_socket = -1;
    439421}
    440422
  • ipc.h

    rb79308b r6cac643  
    4444
    4545void ipc_master_free_one( struct bitlbee_child *child );
    46 void ipc_master_free_fd( int fd );
    4746void ipc_master_free_all();
    48 
    49 void ipc_child_disable();
    5047
    5148void ipc_to_master( char **cmd );
  • irc.c

    rb79308b r6cac643  
    4646}
    4747
    48 static char *set_eval_charset( set_t *set, char *value )
    49 {
    50         irc_t *irc = set->data;
    51         GIConv ic, oc;
    52 
    53         if( g_strcasecmp( value, "none" ) == 0 )
    54                 value = g_strdup( "utf-8" );
    55 
    56         if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 )
    57         {
    58                 return NULL;
    59         }
    60         if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
    61         {
    62                 g_iconv_close( ic );
    63                 return NULL;
    64         }
    65        
    66         if( irc->iconv != (GIConv) -1 )
    67                 g_iconv_close( irc->iconv );
    68         if( irc->oconv != (GIConv) -1 )
    69                 g_iconv_close( irc->oconv );
    70        
    71         irc->iconv = ic;
    72         irc->oconv = oc;
    73 
    74         return value;
    75 }
    76 
    7748irc_t *irc_new( int fd )
    7849{
     
    9768        irc->mynick = g_strdup( ROOT_NICK );
    9869        irc->channel = g_strdup( ROOT_CHAN );
    99        
    100         irc->iconv = (GIConv) -1;
    101         irc->oconv = (GIConv) -1;
    10270       
    10371        if( global.conf->hostname )
     
    155123        set_add( &irc->set, "private", "true", set_eval_bool, irc );
    156124        set_add( &irc->set, "query_order", "lifo", NULL, irc );
    157         set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc );
    158125        set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
    159126        set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc );
     
    164131        conf_loaddefaults( irc );
    165132       
    166         /* Evaluator sets the iconv/oconv structures. */
    167         set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) );
    168        
    169133        return( irc );
    170134}
     
    204168        if( irc->sendbuffer && !immed )
    205169        {
    206                 /* Set up a timeout event that should shut down the connection
    207                    in a second, just in case ..._write doesn't do it first. */
     170                /* We won't read from this socket anymore. Instead, we'll connect a timer
     171                   to it that should shut down the connection in a second, just in case
     172                   bitlbee_.._write doesn't do it first. */
    208173               
    209174                b_event_remove( irc->r_watch_source_id );
    210                 irc->r_watch_source_id = 0;
    211                
    212                 b_event_remove( irc->ping_source_id );
    213                 irc->ping_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc );
     175                irc->r_watch_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc );
    214176        }
    215177        else
     
    227189
    228190/* Because we have no garbage collection, this is quite annoying */
    229 void irc_free( irc_t * irc )
    230 {
     191void irc_free(irc_t * irc)
     192{
     193        account_t *account;
    231194        user_t *user, *usertmp;
    232195       
     
    237200                        irc_usermsg( irc, "Error while saving settings!" );
    238201       
     202        closesocket( irc->fd );
     203       
     204        if( irc->ping_source_id > 0 )
     205                b_event_remove( irc->ping_source_id );
     206        b_event_remove( irc->r_watch_source_id );
     207        if( irc->w_watch_source_id > 0 )
     208                b_event_remove( irc->w_watch_source_id );
     209       
    239210        irc_connection_list = g_slist_remove( irc_connection_list, irc );
    240211       
    241         while( irc->accounts )
    242         {
    243                 if( irc->accounts->ic )
    244                         imc_logout( irc->accounts->ic, FALSE );
    245                 else if( irc->accounts->reconnect )
    246                         cancel_auto_reconnect( irc->accounts );
    247                
    248                 if( irc->accounts->ic == NULL )
    249                         account_del( irc, irc->accounts );
     212        for (account = irc->accounts; account; account = account->next) {
     213                if (account->ic) {
     214                        imc_logout(account->ic, TRUE);
     215                } else if (account->reconnect) {
     216                        cancel_auto_reconnect(account);
     217                }
     218        }
     219       
     220        g_free(irc->sendbuffer);
     221        g_free(irc->readbuffer);
     222       
     223        g_free(irc->nick);
     224        g_free(irc->user);
     225        g_free(irc->host);
     226        g_free(irc->realname);
     227        g_free(irc->password);
     228       
     229        g_free(irc->myhost);
     230        g_free(irc->mynick);
     231       
     232        g_free(irc->channel);
     233       
     234        while (irc->queries != NULL)
     235                query_del(irc, irc->queries);
     236       
     237        while (irc->accounts)
     238                if (irc->accounts->ic == NULL)
     239                        account_del(irc, irc->accounts);
    250240                else
    251241                        /* Nasty hack, but account_del() doesn't work in this
    252242                           case and we don't want infinite loops, do we? ;-) */
    253243                        irc->accounts = irc->accounts->next;
    254         }
    255        
    256         while( irc->queries != NULL )
    257                 query_del( irc, irc->queries );
    258        
    259         while( irc->set )
    260                 set_del( &irc->set, irc->set->key );
    261        
    262         if (irc->users != NULL)
    263         {
     244       
     245        while (irc->set)
     246                set_del(&irc->set, irc->set->key);
     247       
     248        if (irc->users != NULL) {
    264249                user = irc->users;
    265                 while( user != NULL )
    266                 {
    267                         g_free( user->nick );
    268                         g_free( user->away );
    269                         g_free( user->handle );
    270                         if( user->user != user->nick ) g_free( user->user );
    271                         if( user->host != user->nick ) g_free( user->host );
    272                         if( user->realname != user->nick ) g_free( user->realname );
    273                         b_event_remove( user->sendbuf_timer );
     250                while (user != NULL) {
     251                        g_free(user->nick);
     252                        g_free(user->away);
     253                        g_free(user->handle);
     254                        if(user->user!=user->nick) g_free(user->user);
     255                        if(user->host!=user->nick) g_free(user->host);
     256                        if(user->realname!=user->nick) g_free(user->realname);
     257                        b_event_remove(user->sendbuf_timer);
    274258                                       
    275259                        usertmp = user;
    276260                        user = user->next;
    277                         g_free( usertmp );
    278                 }
    279         }
    280        
    281         if( irc->ping_source_id > 0 )
    282                 b_event_remove( irc->ping_source_id );
    283         if( irc->r_watch_source_id > 0 )
    284                 b_event_remove( irc->r_watch_source_id );
    285         if( irc->w_watch_source_id > 0 )
    286                 b_event_remove( irc->w_watch_source_id );
    287        
    288         closesocket( irc->fd );
    289         irc->fd = -1;
    290        
    291         g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL );
    292         g_hash_table_destroy( irc->userhash );
    293        
    294         g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL );
    295         g_hash_table_destroy( irc->watches );
    296        
    297         if( irc->iconv != (GIConv) -1 )
    298                 g_iconv_close( irc->iconv );
    299         if( irc->oconv != (GIConv) -1 )
    300                 g_iconv_close( irc->oconv );
    301        
    302         g_free( irc->sendbuffer );
    303         g_free( irc->readbuffer );
    304        
    305         g_free( irc->nick );
    306         g_free( irc->user );
    307         g_free( irc->host );
    308         g_free( irc->realname );
    309         g_free( irc->password );
    310        
    311         g_free( irc->myhost );
    312         g_free( irc->mynick );
    313        
    314         g_free( irc->channel );
    315        
    316         g_free( irc->last_target );
    317        
    318         g_free( irc );
     261                        g_free(usertmp);
     262                }
     263        }
     264       
     265        g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL);
     266        g_hash_table_destroy(irc->userhash);
     267       
     268        g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL);
     269        g_hash_table_destroy(irc->watches);
     270       
     271        g_free(irc);
    319272       
    320273        if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON )
     
    337290void irc_process( irc_t *irc )
    338291{
    339         char **lines, *temp, **cmd;
     292        char **lines, *temp, **cmd, *cs;
    340293        int i;
    341294
     
    346299                for( i = 0; *lines[i] != '\0'; i ++ )
    347300                {
    348                         char *conv = NULL;
     301                        char conv[IRC_MAX_LINE+1];
    349302                       
    350                         /* [WvG] If the last line isn't empty, it's an incomplete line and we
    351                            should wait for the rest to come in before processing it. */
     303                        /* [WvG] Because irc_tokenize splits at every newline, the lines[] list
     304                            should end with an empty string. This is why this actually works.
     305                            Took me a while to figure out, Maurits. :-P */
    352306                        if( lines[i+1] == NULL )
    353307                        {
     
    359313                        }
    360314                       
    361                         if( irc->iconv != (GIConv) -1 )
    362                         {
    363                                 gsize bytes_read, bytes_written;
    364                                
    365                                 conv = g_convert_with_iconv( lines[i], -1, irc->iconv,
    366                                                              &bytes_read, &bytes_written, NULL );
    367                                
    368                                 if( conv == NULL || bytes_read != strlen( lines[i] ) )
     315                        if( ( cs = set_getstr( &irc->set, "charset" ) ) )
     316                        {
     317                                conv[IRC_MAX_LINE] = 0;
     318                                if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 )
    369319                                {
    370320                                        /* GLib can do strange things if things are not in the expected charset,
     
    378328                                                                  "expect by changing the charset setting. See "
    379329                                                                  "`help set charset' for more information. Your "
    380                                                                   "message was ignored.",
    381                                                                   set_getstr( &irc->set, "charset" ) );
    382                                                
    383                                                 g_free( conv );
    384                                                 conv = NULL;
     330                                                                  "message was ignored.", cs );
     331                                                *conv = 0;
    385332                                        }
    386333                                        else
    387334                                        {
    388335                                                irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost,
    389                                                            "Warning: invalid characters received at login time." );
     336                                                           "Warning: invalid (non-UTF8) characters received at login time." );
    390337                                               
    391                                                 conv = g_strdup( lines[i] );
     338                                                strncpy( conv, lines[i], IRC_MAX_LINE );
    392339                                                for( temp = conv; *temp; temp ++ )
    393340                                                        if( *temp & 0x80 )
     
    398345                        }
    399346                       
    400                         if( lines[i] )
    401                         {
    402                                 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    403                                         continue;
    404                                 irc_exec( irc, cmd );
    405                                 g_free( cmd );
    406                         }
     347                        if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
     348                                continue;
     349                        irc_exec( irc, cmd );
    407350                       
    408                         g_free( conv );
     351                        g_free( cmd );
    409352                       
    410353                        /* Shouldn't really happen, but just in case... */
     
    430373char **irc_tokenize( char *buffer )
    431374{
    432         int i, j, n = 3;
     375        int i, j;
    433376        char **lines;
    434377
    435         /* Allocate n+1 elements. */
    436         lines = g_new( char *, n + 1 );
     378        /* Count the number of elements we're gonna need. */
     379        for( i = 0, j = 1; buffer[i] != '\0'; i ++ )
     380        {
     381                if( buffer[i] == '\n' )
     382                        if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
     383                                j ++;
     384        }
     385       
     386        /* Allocate j+1 elements. */
     387        lines = g_new( char *, j + 1 );
     388       
     389        /* NULL terminate our list. */
     390        lines[j] = NULL;
    437391       
    438392        lines[0] = buffer;
    439393       
    440         /* Split the buffer in several strings, and accept any kind of line endings,
    441          * knowing that ERC on Windows may send something interesting like \r\r\n,
    442          * and surely there must be clients that think just \n is enough... */
    443         for( i = 0, j = 0; buffer[i] != '\0'; i ++ )
    444         {
    445                 if( buffer[i] == '\r' || buffer[i] == '\n' )
    446                 {
    447                         while( buffer[i] == '\r' || buffer[i] == '\n' )
    448                                 buffer[i++] = '\0';
     394        /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
     395         * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
     396         */
     397        for( i = 0, j = 0; buffer[i] != '\0'; i ++)
     398        {
     399                if( buffer[i] == '\n' )
     400                {
     401                        buffer[i] = '\0';
    449402                       
    450                         lines[++j] = buffer + i;
    451                        
    452                         if( j >= n )
    453                         {
    454                                 n *= 2;
    455                                 lines = g_renew( char *, lines, n + 1 );
    456                         }
    457 
    458                         if( buffer[i] == '\0' )
    459                                 break;
    460                 }
    461         }
    462        
    463         /* NULL terminate our list. */
    464         lines[++j] = NULL;
    465        
    466         return lines;
     403                        if( i > 0 && buffer[i-1] == '\r' )
     404                                buffer[i-1] = '\0';
     405                        if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
     406                                lines[++j] = buffer + i + 1;
     407                }
     408        }
     409       
     410        return( lines );
    467411}
    468412
     
    598542
    599543        return;
     544
    600545}
    601546
     
    603548{
    604549        int size;
    605         char line[IRC_MAX_LINE+1];
     550        char line[IRC_MAX_LINE+1], *cs;
    606551               
    607552        /* Don't try to write anything new anymore when shutting down. */
     
    609554                return;
    610555       
    611         memset( line, 0, sizeof( line ) );
     556        line[IRC_MAX_LINE] = 0;
    612557        g_vsnprintf( line, IRC_MAX_LINE - 2, format, params );
     558       
    613559        strip_newlines( line );
    614        
    615         if( irc->oconv != (GIConv) -1 )
    616         {
    617                 gsize bytes_read, bytes_written;
    618                 char *conv;
    619                
    620                 conv = g_convert_with_iconv( line, -1, irc->oconv,
    621                                              &bytes_read, &bytes_written, NULL );
    622 
    623                 if( bytes_read == strlen( line ) )
    624                         strncpy( line, conv, IRC_MAX_LINE - 2 );
    625                
    626                 g_free( conv );
    627         }
    628         g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 );
     560        if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
     561        {
     562                char conv[IRC_MAX_LINE+1];
     563               
     564                conv[IRC_MAX_LINE] = 0;
     565                if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 )
     566                        strcpy( line, conv );
     567        }
     568        strcat( line, "\r\n" );
    629569       
    630570        if( irc->sendbuffer != NULL )
     
    799739        irc_spawn( irc, u );
    800740       
    801         irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n"
    802                           "If you've never used BitlBee before, please do read the help "
    803                           "information using the \x02help\x02 command. Lots of FAQs are "
    804                           "answered there.\n"
    805                           "If you already have an account on this server, just use the "
    806                           "\x02identify\x02 command to identify yourself." );
     741        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." );
    807742       
    808743        if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON )
     
    810745       
    811746        irc->status |= USTATUS_LOGGED_IN;
    812        
    813         /* This is for bug #209 (use PASS to identify to NickServ). */
    814         if( irc->password != NULL )
    815         {
    816                 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL };
    817                
    818                 irc_setpass( irc, NULL );
    819                 root_command( irc, send_cmd );
    820                 g_free( send_cmd[1] );
    821         }
    822747}
    823748
  • irc.h

    rb79308b r6cac643  
    6161        char *sendbuffer;
    6262        char *readbuffer;
    63         GIConv iconv, oconv;
    6463
    6564        int sentbytes;
     
    7069        char *host;
    7170        char *realname;
    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. */
     71        char *password;
    7572
    7673        char umode[8];
  • irc_commands.c

    rb79308b r6cac643  
    3030static void irc_cmd_pass( irc_t *irc, char **cmd )
    3131{
    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 ) )
     32        if( global.conf->auth_pass && strcmp( cmd[1], global.conf->auth_pass ) == 0 )
    4833        {
    4934                irc->status |= USTATUS_AUTHORIZED;
    5035                irc_check_login( irc );
    5136        }
    52         else if( global.conf->auth_pass )
     37        else
    5338        {
    5439                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 );
    6140        }
    6241}
     
    10988static void irc_cmd_oper( irc_t *irc, char **cmd )
    11089{
    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 ) )
     90        if( global.conf->oper_pass && strcmp( cmd[2], global.conf->oper_pass ) == 0 )
    11591        {
    11692                irc_umode_set( irc, "+o", 1 );
     
    278254                        if( cmd[1] != irc->last_target )
    279255                        {
    280                                 g_free( irc->last_target );
     256                                if( irc->last_target )
     257                                        g_free( irc->last_target );
    281258                                irc->last_target = g_strdup( cmd[1] );
    282259                        }
     
    598575
    599576static const command_t irc_commands[] = {
    600         { "pass",        1, irc_cmd_pass,        0 },
     577        { "pass",        1, irc_cmd_pass,        IRC_CMD_PRE_LOGIN },
    601578        { "user",        4, irc_cmd_user,        IRC_CMD_PRE_LOGIN },
    602579        { "nick",        1, irc_cmd_nick,        0 },
  • lib/Makefile

    rb79308b r6cac643  
    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 xmltree.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
    1313
    1414CFLAGS += -Wall
     
    1818all: lib.o
    1919check: all
    20 lcov: check
     20lcov:
    2121gcov:
    2222        gcov *.c
  • lib/arc.c

    rb79308b r6cac643  
    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!
    137133*/
    138134
    139 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to )
     135int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password )
    140136{
    141137        struct arc_state *st;
    142138        unsigned char *key;
    143         char *padded = NULL;
    144         int key_len, i, padded_len;
     139        int key_len, i;
    145140       
    146141        key_len = strlen( password ) + ARC_IV_LEN;
    147142        if( clear_len <= 0 )
    148143                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         }
    166144       
    167145        /* Prepare buffers and the key + IV */
     
    183161       
    184162        g_free( st );
    185         g_free( padded );
    186163       
    187164        return clear_len + ARC_IV_LEN;
  • lib/arc.h

    rb79308b r6cac643  
    3131};
    3232
    33 #ifndef G_GNUC_MALLOC
    34 #define G_GNUC_MALLOC
    35 #endif
    36 
    37 G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
     33struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
    3834unsigned char arc_getbyte( struct arc_state *st );
    39 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to );
     35int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password );
    4036int arc_decode( unsigned char *crypt, int crypt_len, char **clear, char *password );
  • lib/base64.c

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

    rb79308b r6cac643  
    5151} GaimIOClosure;
    5252
    53 static GMainLoop *loop = NULL;
     53static GMainLoop *loop;
    5454
    5555void b_main_init()
    5656{
    57         if( loop == NULL )
    58                 loop = g_main_new( FALSE );
     57        loop = g_main_new( FALSE );
    5958}
    6059
  • lib/misc.c

    rb79308b r6cac643  
    3333#define BITLBEE_CORE
    3434#include "nogaim.h"
    35 #include "base64.h"
    3635#include <stdio.h>
    3736#include <stdlib.h>
     
    598597                return sockerr_again();
    599598}
    600 
    601 /* Returns values: -1 == Failure (base64-decoded to something unexpected)
    602                     0 == Okay
    603                     1 == Password doesn't match the hash. */
    604 int 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

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

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

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

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

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

    rb79308b r6cac643  
    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        
    7064        conn->func = func;
    7165        conn->data = data;
    7266        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. */
    242 int 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 
    248233void ssl_disconnect( void *conn_ )
    249234{
  • lib/url.c

    rb79308b r6cac643  
    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+1];
     31        char s[MAX_STRING];
    3232        char *i;
    3333       
    34         memset( url, 0, sizeof( url_t ) );
    35         memset( s, 0, sizeof( s ) );
    36        
    37         /* protocol:// */
     34        /* protocol://                                                  */
    3835        if( ( i = strstr( set_url, "://" ) ) == NULL )
    3936        {
     
    5249                        url->proto = PROTO_SOCKS5;
    5350                else
    54                         return 0;
    55                
     51                {
     52                        return( 0 );
     53                }
    5654                strncpy( s, i + 3, MAX_STRING );
    5755        }
    5856       
    59         /* Split */
     57        /* Split                                                        */
    6058        if( ( i = strchr( s, '/' ) ) == NULL )
    6159        {
     
    6967        strncpy( url->host, s, MAX_STRING );
    7068       
    71         /* Check for username in host field */
     69        /* Check for username in host field                             */
    7270        if( strrchr( url->host, '@' ) != NULL )
    7371        {
     
    7876                *url->pass = 0;
    7977        }
    80         /* If not: Fill in defaults */
     78        /* If not: Fill in defaults                                     */
    8179        else
    8280        {
     
    8482        }
    8583       
    86         /* Password? */
     84        /* Password?                                                    */
    8785        if( ( i = strchr( url->user, ':' ) ) != NULL )
    8886        {
     
    9088                strcpy( url->pass, i + 1 );
    9189        }
    92         /* Port number? */
     90        /* Port number?                                                 */
    9391        if( ( i = strchr( url->host, ':' ) ) != NULL )
    9492        {
  • lib/url.h

    rb79308b r6cac643  
    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+1];
    39         char file[MAX_STRING+1];
    40         char user[MAX_STRING+1];
    41         char pass[MAX_STRING+1];
     38        char host[MAX_STRING];
     39        char file[MAX_STRING];
     40        char user[MAX_STRING];
     41        char pass[MAX_STRING];
    4242} url_t;
    4343
  • protocols/Makefile

    rb79308b r6cac643  
    2727all: protocols.o
    2828check: all
    29 lcov: check
     29lcov:
    3030gcov:
    3131        gcov *.c
  • protocols/jabber/Makefile

    rb79308b r6cac643  
    1010
    1111# [SH] Program variables
    12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o si.o s5bytestream.o
     12objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o si.o s5bytestream.o
    1313
    1414CFLAGS += -Wall
     
    1818all: jabber_mod.o
    1919check: all
    20 lcov: check
     20lcov:
    2121gcov:
    2222        gcov *.c
  • protocols/jabber/io.c

    rb79308b r6cac643  
    241241        }
    242242       
    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;
     243        /* EAGAIN/etc or a successful read. */
     244        return TRUE;
    250245}
    251246
     
    526521           from the server too. */
    527522        xt_free( jd->xt );      /* In case we're RE-starting. */
    528         jd->xt = xt_new( jabber_handlers, ic );
     523        jd->xt = xt_new( ic );
     524        jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers;
    529525       
    530526        if( jd->r_inpa <= 0 )
  • protocols/jabber/iq.c

    rb79308b r6cac643  
    534534}
    535535
    536 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    537 
    538536int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name )
    539537{
     
    551549        xt_add_attr( node, "xmlns", XMLNS_ROSTER );
    552550        node = jabber_make_packet( "iq", "set", NULL, node );
    553         jabber_cache_add( ic, node, jabber_add_to_roster_callback );
    554551       
    555552        st = jabber_write_packet( ic, node );
    556553       
     554        xt_free_node( node );
    557555        return st;
    558 }
    559 
    560 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
    561 {
    562         char *s, *jid = NULL;
    563         struct xt_node *c;
    564        
    565         if( ( c = xt_find_node( orig->children, "query" ) ) &&
    566             ( c = xt_find_node( c->children, "item" ) ) &&
    567             ( jid = xt_find_attr( c, "jid" ) ) &&
    568             ( s = xt_find_attr( node, "type" ) ) &&
    569             strcmp( s, "result" ) == 0 )
    570         {
    571                 if( imcb_find_buddy( ic, jid ) == NULL )
    572                         imcb_add_buddy( ic, jid, NULL );
    573         }
    574         else
    575         {
    576                 imcb_log( ic, "Error while adding `%s' to your contact list.",
    577                           jid ? jid : "(unknown handle)" );
    578         }
    579        
    580         return XT_HANDLED;
    581556}
    582557
  • protocols/jabber/jabber.c

    rb79308b r6cac643  
    267267        xt_free( jd->xt );
    268268       
    269         g_free( jd->cached_id_prefix );
    270269        g_free( jd->away_message );
    271270        g_free( jd->username );
  • protocols/jabber/jabber_util.c

    rb79308b r6cac643  
    250250};
    251251
    252 static void jabber_buddy_ask_yes( void *data )
    253 {
    254         struct jabber_buddy_ask_data *bla = data;
    255        
     252static void jabber_buddy_ask_yes( gpointer w, struct jabber_buddy_ask_data *bla )
     253{
    256254        presence_send_request( bla->ic, bla->handle, "subscribed" );
    257255       
     
    263261}
    264262
    265 static void jabber_buddy_ask_no( void *data )
    266 {
    267         struct jabber_buddy_ask_data *bla = data;
    268        
     263static void jabber_buddy_ask_no( gpointer w, struct jabber_buddy_ask_data *bla )
     264{
    269265        presence_send_request( bla->ic, bla->handle, "subscribed" );
    270266       
  • protocols/jabber/sasl.c

    rb79308b r6cac643  
    2121*                                                                           *
    2222\***************************************************************************/
    23 
    24 #include <ctype.h>
    2523
    2624#include "jabber.h"
     
    109107}
    110108
    111 /* Non-static function, but not mentioned in jabber.h because it's for internal
    112    use, just that the unittest should be able to reach it... */
    113 char *sasl_get_part( char *data, char *field )
     109static char *sasl_get_part( char *data, char *field )
    114110{
    115111        int i, len;
    116112       
    117113        len = strlen( field );
    118        
    119         while( isspace( *data ) || *data == ',' )
    120                 data ++;
    121114       
    122115        if( g_strncasecmp( data, field, len ) == 0 && data[len] == '=' )
     
    136129                        }
    137130                       
    138                         /* If we got a comma, we got a new field. Check it,
    139                            find the next key after it. */
    140                         if( data[i] == ',' )
     131                        /* If we got a comma, we got a new field. Check it. */
     132                        if( data[i] == ',' &&
     133                            g_strncasecmp( data + i + 1, field, len ) == 0 &&
     134                            data[i+len+1] == '=' )
    141135                        {
    142                                 while( isspace( data[i] ) || data[i] == ',' )
    143                                         i ++;
    144                                
    145                                 if( g_strncasecmp( data + i, field, len ) == 0 &&
    146                                     data[i+len] == '=' )
    147                                 {
    148                                         i += len + 1;
    149                                         break;
    150                                 }
     136                                i += len + 2;
     137                                break;
    151138                        }
    152139                }
  • protocols/msn/Makefile

    rb79308b r6cac643  
    1818all: msn_mod.o
    1919check: all
    20 lcov: check
     20lcov:
    2121gcov:
    2222        gcov *.c
  • protocols/msn/msn.h

    rb79308b r6cac643  
    2929#define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r"
    3030
    31 #ifdef DEBUG_MSN
     31#ifdef DEBUG
    3232#define debug( text... ) imcb_log( ic, text );
    3333#else
  • protocols/msn/msn_util.c

    rb79308b r6cac643  
    9090};
    9191
    92 static void msn_buddy_ask_yes( void *data )
    93 {
    94         struct msn_buddy_ask_data *bla = data;
    95        
     92static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla )
     93{
    9694        msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname );
    9795       
     
    104102}
    105103
    106 static void msn_buddy_ask_no( void *data )
    107 {
    108         struct msn_buddy_ask_data *bla = data;
    109        
     104static void msn_buddy_ask_no( gpointer w, struct msn_buddy_ask_data *bla )
     105{
    110106        msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname );
    111107       
  • protocols/msn/ns.c

    rb79308b r6cac643  
    3434static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
    3535
    36 static void msn_auth_got_passport_token( struct msn_auth_data *mad );
     36static void msn_auth_got_passport_id( struct passport_reply *rep );
    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_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
     216                        if( !passport_get_id( msn_auth_got_passport_id, 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_token( struct msn_auth_data *mad )
     676static void msn_auth_got_passport_id( struct passport_reply *rep )
    677677{
    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 );
     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" );
     687                imc_logout( ic, TRUE );
     688        }
     689        else
     690        {
     691                g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );
    691692                msn_write( ic, buf, strlen( buf ) );
    692693        }
    693         else
    694         {
    695                 imcb_error( ic, "Error during Passport authentication: %s", mad->error );
    696                 imc_logout( ic, TRUE );
    697         }
    698694}
  • protocols/msn/passport.c

    rb79308b r6cac643  
    1 /** passport.c
     1/* passport.c
    22 *
    3  * Functions to login to Microsoft Passport service for Messenger
    4  * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net>
     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>
    56 *
    67 * This program is free software; you can redistribute it and/or modify             
     
    2324#include "msn.h"
    2425#include "bitlbee.h"
    25 #include "url.h"
    26 #include "misc.h"
    27 #include "xmltree.h"
    2826#include <ctype.h>
    2927#include <errno.h>
    3028
    31 static int passport_get_token_real( struct msn_auth_data *mad );
    32 static void passport_get_token_ready( struct http_request *req );
    33 
    34 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie )
    35 {
    36         struct msn_auth_data *mad = g_new0( struct msn_auth_data, 1 );
    37         int i;
    38        
    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 );
    61 }
    62 
    63 static int passport_get_token_real( struct msn_auth_data *mad )
    64 {
    65         char *post_payload, *post_request;
     29#define MSN_BUF_LEN 8192
     30
     31static char *prd_cached = NULL;
     32
     33static int passport_get_id_real( gpointer func, gpointer data, char *header );
     34static void passport_get_id_ready( struct http_request *req );
     35
     36static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header );
     37static void passport_retrieve_dalogin_ready( struct http_request *req );
     38
     39static char *passport_create_header( char *cookie, char *email, char *pwd );
     40static void destroy_reply( struct passport_reply *rep );
     41
     42int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie )
     43{
     44        char *header = passport_create_header( cookie, username, password );
     45       
     46        if( prd_cached == NULL )
     47                return passport_retrieve_dalogin( func, data, header );
     48        else
     49                return passport_get_id_real( func, data, header );
     50}
     51
     52static int passport_get_id_real( gpointer func, gpointer data, char *header )
     53{
     54        struct passport_reply *rep;
     55        char *server, *dummy, *reqs;
    6656        struct http_request *req;
    67         url_t url;
    68        
    69         url_set( &url, mad->url );
    70        
    71         post_payload = g_markup_printf_escaped( SOAP_AUTHENTICATION_PAYLOAD,
    72                                                 mad->username,
    73                                                 mad->password,
    74                                                 mad->cookie );
    75        
    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 );
    83        
    84         g_free( post_request );
    85         g_free( post_payload );
    86        
    87         return req != NULL;
    88 }
    89 
    90 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data );
    91 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data );
    92 
    93 static 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 
    99 static void passport_get_token_ready( struct http_request *req )
    100 {
    101         struct msn_auth_data *mad = req->data;
    102         struct xt_parser *parser;
    103        
    104         g_free( mad->url );
    105         g_free( mad->error );
    106         mad->url = mad->error = NULL;
    107        
    108         if( req->status_code == 200 )
    109         {
    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 );
     57       
     58        rep = g_new0( struct passport_reply, 1 );
     59        rep->data = data;
     60        rep->func = func;
     61        rep->header = header;
     62       
     63        server = g_strdup( prd_cached );
     64        dummy = strchr( server, '/' );
     65       
     66        if( dummy == NULL )
     67        {
     68                destroy_reply( rep );
     69                return( 0 );
     70        }
     71       
     72        reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
     73       
     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 );
     84}
     85
     86static void passport_get_id_ready( struct http_request *req )
     87{
     88        struct passport_reply *rep = req->data;
     89       
     90        if( !g_slist_find( msn_connections, rep->data ) )
     91        {
     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                }
    114115        }
    115116        else
    116117        {
    117                 mad->error = g_strdup_printf( "HTTP error %d (%s)", req->status_code,
    118                                               req->status_string ? req->status_string : "unknown" );
    119         }
    120        
    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         }
    140 }
    141 
    142 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data )
    143 {
    144         struct msn_auth_data *mad = data;
    145         char *s;
    146        
    147         if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 )
    148                 mad->token = g_memdup( node->text, node->text_len + 1 );
    149        
    150         return XT_HANDLED;
    151 }
    152 
    153 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data )
    154 {
    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" );
    159        
    160         if( redirect && redirect->text_len && mad->ttl-- > 0 )
    161                 mad->url = g_memdup( redirect->text, redirect->text_len + 1 );
    162        
    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" );
    168        
    169         return XT_HANDLED;
    170 }
     118                rep->error_string = g_strdup_printf( "HTTP error: %s",
     119                                      req->status_string ? req->status_string : "Unknown error" );
     120        }
     121       
     122        rep->func( rep );
     123        destroy_reply( rep );
     124}
     125
     126static char *passport_create_header( char *cookie, char *email, char *pwd )
     127{
     128        char *buffer;
     129        char *currenttoken;
     130        char *email_enc, *pwd_enc;
     131       
     132        currenttoken = strstr( cookie, "lc=" );
     133        if( currenttoken == NULL )
     134                return NULL;
     135       
     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;
     153}
     154
     155static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
     156{
     157        struct passport_reply *rep = g_new0( struct passport_reply, 1 );
     158        struct http_request *req;
     159       
     160        rep->data = data;
     161        rep->func = func;
     162        rep->header = header;
     163       
     164        req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep );
     165       
     166        if( !req )
     167                destroy_reply( rep );
     168       
     169        return( req != NULL );
     170}
     171
     172static 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       
     219failure:       
     220        rep->func( rep );
     221        destroy_reply( rep );
     222}
     223
     224static 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

    rb79308b r6cac643  
     1#ifndef __PASSPORT_H__
     2#define __PASSPORT_H__
    13/* passport.h
    24 *
    3  * Functions to login to Microsoft Passport service for Messenger
    4  * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net>
     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>
    58 *
    69 * This program is free software; you can redistribute it and/or modify             
     
    1518 * You should have received a copy of the GNU General Public License               
    1619 * along with this program; if not, write to the Free Software                     
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA         
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA         
    1821 */
    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__
    2522
    2623#include <stdio.h>
     
    3633#include "nogaim.h"
    3734
    38 #define MAX_PASSPORT_PWLEN 16
    39 
    40 struct msn_auth_data
     35struct passport_reply
    4136{
    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;
     37        void (*func)( struct passport_reply * );
     38        void *data;
     39        char *result;
     40        char *header;
     41        char *error_string;
    5642};
    5743
    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 
    111 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie );
     44int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie );
    11245
    11346#endif /* __PASSPORT_H__ */
  • protocols/nogaim.c

    rb79308b r6cac643  
    343343/* dialogs.c */
    344344
    345 void imcb_ask( struct im_connection *ic, char *msg, void *data,
    346                query_callback doit, query_callback dont )
     345void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont )
    347346{
    348347        query_add( ic->irc, ic, msg, doit, dont, data );
     
    496495};
    497496
    498 void show_got_added_no( void *data )
    499 {
    500         g_free( ((struct show_got_added_data*)data)->handle );
     497void show_got_added_no( gpointer w, struct show_got_added_data *data )
     498{
     499        g_free( data->handle );
    501500        g_free( data );
    502501}
    503502
    504 void show_got_added_yes( void *data )
    505 {
    506         struct show_got_added_data *sga = data;
    507        
    508         sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL );
    509         /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */
    510        
    511         return show_got_added_no( data );
     503void show_got_added_yes( gpointer w, struct show_got_added_data *data )
     504{
     505        data->ic->acc->prpl->add_buddy( data->ic, data->handle, NULL );
     506        /* imcb_add_buddy( data->ic, NULL, data->handle, data->handle ); */
     507       
     508        return show_got_added_no( w, data );
    512509}
    513510
  • protocols/nogaim.h

    rb79308b r6cac643  
    4242#include "account.h"
    4343#include "proxy.h"
    44 #include "query.h"
    4544#include "md5.h"
    4645#include "ft.h"
     
    266265 * - 'doit' or 'dont' will be called depending of the answer of the user.
    267266 */
    268 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont );
     267G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont );
    269268G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname );
    270269
  • protocols/oscar/Makefile

    rb79308b r6cac643  
    1818all: oscar_mod.o
    1919check: all
    20 lcov: check
     20lcov:
    2121gcov:
    2222        gcov *.c
  • protocols/oscar/oscar.c

    rb79308b r6cac643  
    10841084}
    10851085
    1086 void oscar_accept_chat(void *data);
    1087 void oscar_reject_chat(void *data);
     1086void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv);
     1087void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv);
    10881088       
    10891089static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
     
    11191119}
    11201120
    1121 static void gaim_icq_authgrant(void *data_) {
    1122         struct icq_auth *data = data_;
     1121static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) {
    11231122        char *uin, message;
    11241123        struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
     
    11351134}
    11361135
    1137 static void gaim_icq_authdeny(void *data_) {
    1138         struct icq_auth *data = data_;
     1136static void gaim_icq_authdeny(gpointer w, struct icq_auth *data) {
    11391137        char *uin, *message;
    11401138        struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
     
    25902588}
    25912589
    2592 void oscar_accept_chat(void *data)
     2590void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv)
    25932591{
    2594         struct aim_chat_invitation * inv = data;
    2595        
    25962592        oscar_chat_join(inv->ic, inv->name, NULL, NULL);
    25972593        g_free(inv->name);
     
    25992595}
    26002596
    2601 void oscar_reject_chat(void *data)
     2597void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv)
    26022598{
    2603         struct aim_chat_invitation * inv = data;
    2604        
    26052599        g_free(inv->name);
    26062600        g_free(inv);
  • protocols/yahoo/Makefile

    rb79308b r6cac643  
    1818all: yahoo_mod.o
    1919check: all
    20 lcov: check
     20lcov:
    2121gcov:
    2222        gcov *.c
  • protocols/yahoo/libyahoo2.c

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

    rb79308b r6cac643  
    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 ? msg : "" );
     317        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
    318318}
    319319
     
    797797}
    798798
    799 static void byahoo_accept_conf( void *data )
    800 {
    801         struct byahoo_conf_invitation *inv = data;
    802        
     799static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )
     800{
    803801        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
    804802        imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
     
    807805}
    808806
    809 static void byahoo_reject_conf( void *data )
    810 {
    811         struct byahoo_conf_invitation *inv = data;
    812        
     807static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )
     808{
    813809        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
    814810        imcb_chat_free( inv->c );
  • query.c

    rb79308b r6cac643  
    3030static query_t *query_default( irc_t *irc );
    3131
    32 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question,
    33                     query_callback yes, query_callback no, void *data )
     32query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data )
    3433{
    3534        query_t *q = g_new0( query_t, 1 );
     
    141140        if( ans )
    142141        {
    143                 if( q->ic )
    144                         imcb_log( q->ic, "Accepted: %s", q->question );
    145                 else
    146                         irc_usermsg( irc, "Accepted: %s", q->question );
    147                 q->yes( q->data );
     142                imcb_log( q->ic, "Accepted: %s", q->question );
     143                q->yes( NULL, q->data );
    148144        }
    149145        else
    150146        {
    151                 if( q->ic )
    152                         imcb_log( q->ic, "Rejected: %s", q->question );
    153                 else
    154                         irc_usermsg( irc, "Rejected: %s", q->question );
    155                 q->no( q->data );
     147                imcb_log( q->ic, "Rejected: %s", q->question );
     148                q->no( NULL, q->data );
    156149        }
    157150        q->data = NULL;
  • query.h

    rb79308b r6cac643  
    2727#define _QUERY_H
    2828
    29 typedef void (*query_callback) ( void *data );
    30 
    3129typedef struct query
    3230{
    3331        struct im_connection *ic;
    3432        char *question;
    35         query_callback yes, no;
     33        void (* yes) ( gpointer w, void *data );
     34        void (* no) ( gpointer w, void *data );
    3635        void *data;
    3736        struct query *next;
    3837} query_t;
    3938
    40 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question,
    41                     query_callback yes, query_callback no, void *data );
     39query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data );
    4240void query_del( irc_t *irc, query_t *q );
    4341void query_del_by_conn( irc_t *irc, struct im_connection *ic );
  • root_commands.c

    rb79308b r6cac643  
    204204}
    205205
    206 struct cmd_account_del_data
    207 {
    208         account_t *a;
    209         irc_t *irc;
    210 };
    211 
    212 void cmd_account_del_yes( void *data )
    213 {
    214         struct cmd_account_del_data *cad = data;
    215         account_t *a;
    216        
    217         for( a = cad->irc->accounts; a && a != cad->a; a = a->next );
    218        
    219         if( a == NULL )
    220         {
    221                 irc_usermsg( cad->irc, "Account already deleted" );
    222         }
    223         else if( a->ic )
    224         {
    225                 irc_usermsg( cad->irc, "Account is still logged in, can't delete" );
    226         }
    227         else
    228         {
    229                 account_del( cad->irc, a );
    230                 irc_usermsg( cad->irc, "Account deleted" );
    231         }
    232         g_free( data );
    233 }
    234 
    235 void cmd_account_del_no( void *data )
    236 {
    237         g_free( data );
    238 }
    239 
    240206static void cmd_account( irc_t *irc, char **cmd )
    241207{
     
    292258                else
    293259                {
    294                         struct cmd_account_del_data *cad;
    295                         char *msg;
    296                        
    297                         cad = g_malloc( sizeof( struct cmd_account_del_data ) );
    298                         cad->a = a;
    299                         cad->irc = irc;
    300                        
    301                         msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will "
    302                                                "also forget all your saved nicknames. If you want "
    303                                                "to change your username/password, use the `account "
    304                                                "set' command. Are you sure you want to delete this "
    305                                                "account?", a->prpl->name, a->user );
    306                         query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
    307                         g_free( msg );
     260                        account_del( irc, a );
     261                        irc_usermsg( irc, "Account deleted" );
    308262                }
    309263        }
     
    603557                        g_free( irc->mynick );
    604558                        irc->mynick = g_strdup( cmd[2] );
    605                        
    606                         if( strcmp( cmd[0], "set_rename" ) != 0 )
    607                                 set_setstr( &irc->set, "root_nick", cmd[2] );
    608559                }
    609560                else if( u->send_handler == buddy_send_handler )
     
    614565                irc_usermsg( irc, "Nick successfully changed" );
    615566        }
    616 }
    617 
    618 char *set_eval_root_nick( set_t *set, char *new_nick )
    619 {
    620         irc_t *irc = set->data;
    621        
    622         if( strcmp( irc->mynick, new_nick ) != 0 )
    623         {
    624                 char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL };
    625                
    626                 cmd_rename( irc, cmd );
    627         }
    628        
    629         return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL;
    630567}
    631568
     
    832769                else
    833770                        irc_usermsg( irc, "%s is empty", set_name );
    834 
    835                 if( strchr( set_name, '/' ) )
    836                         irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." );
    837771        }
    838772        else
  • set.c

    rb79308b r6cac643  
    230230        return value;
    231231}
     232
     233char *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

    rb79308b r6cac643  
    9797char *set_eval_to_char( set_t *set, char *value );
    9898char *set_eval_ops( set_t *set, char *value );
     99char *set_eval_charset( set_t *set, char *value );
    99100
    100101#endif /* __SET_H__ */
  • storage_xml.c

    rb79308b r6cac643  
    8080                char *nick = xml_attr( attr_names, attr_values, "nick" );
    8181                char *pass = xml_attr( attr_names, attr_values, "password" );
    82                 int st;
     82                md5_byte_t *pass_dec = NULL;
    8383               
    8484                if( !nick || !pass )
     
    8787                                     "Missing attributes for %s element", element_name );
    8888                }
    89                 else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 )
    90                 {
    91                         xd->pass_st = XML_PASS_WRONG;
     89                else if( base64_decode( pass, &pass_dec ) != 21 )
     90                {
    9291                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
    9392                                     "Error while decoding password attribute" );
    9493                }
    95                 else if( st == 0 )
    96                 {
    97                         if( xd->pass_st != XML_PASS_CHECK_ONLY )
    98                                 xd->pass_st = XML_PASS_OK;
    99                 }
    10094                else
    10195                {
    102                         xd->pass_st = XML_PASS_WRONG;
    103                         g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
    104                                      "Password mismatch" );
    105                 }
     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 );
    106125        }
    107126        else if( xd->pass_st < XML_PASS_OK )
     
    409428                int pass_len;
    410429               
    411                 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 );
     430                pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );
    412431                pass_b64 = base64_encode( pass_cr, pass_len );
    413432                g_free( pass_cr );
  • tests/Makefile

    rb79308b r6cac643  
    1111distclean: clean
    1212
    13 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o
     13main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o 
    1414
    15 test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_crypting.o check_set.o check_jabber_sasl.o
     15test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_crypting.o check_set.o
    1616
    1717check: $(test_objs) $(addprefix ../, $(main_objs)) ../protocols/protocols.o ../lib/lib.o
  • tests/check.c

    rb79308b r6cac643  
    6666Suite *set_suite(void);
    6767
    68 /* From check_jabber_sasl.c */
    69 Suite *jabber_sasl_suite(void);
    70 
    7168int main (int argc, char **argv)
    7269{
     
    114111        srunner_add_suite(sr, crypting_suite());
    115112        srunner_add_suite(sr, set_suite());
    116         srunner_add_suite(sr, jabber_sasl_suite());
    117113        if (no_fork)
    118114                srunner_set_fork_status(sr, CK_NOFORK);
  • tests/check_arc.c

    rb79308b r6cac643  
    77#include "arc.h"
    88
    9 char *password = "ArcVier";
     9char *password = "TotT";
    1010
    1111char *clear_tests[] =
     
    1414        "ItllBeBitlBee",
    1515        "One more boring password",
    16         "Hoi hoi",
    1716        NULL
    1817};
     
    2928                int len;
    3029               
    31                 len = arc_encode( clear_tests[i], 0, &crypted, password, 12 );
     30                len = arc_encode( clear_tests[i], 0, &crypted, password );
    3231                len = arc_decode( crypted, len, &decrypted, password );
    3332               
     
    4241struct
    4342{
    44         unsigned char crypted[30];
     43        unsigned char crypted[24];
    4544        int len;
    4645        char *decrypted;
    4746} decrypt_tests[] = {
    48         /* One block with padding. */
    4947        {
    5048                {
    51                         0x3f, 0x79, 0xb0, 0xf5, 0x91, 0x56, 0xd2, 0x1b, 0xd1, 0x4b, 0x67, 0xac,
    52                         0xb1, 0x31, 0xc9, 0xdb, 0xf9, 0xaa
    53                 }, 18, "short pass"
     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"
    5452        },
    55        
    56         /* Two blocks with padding. */
    5753        {
    5854                {
    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"
     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"
    6358        },
    64 
    65         /* This string is exactly two "blocks" long, to make sure unpadded strings also decrypt
    66            properly. */
    6759        {
    6860                {
    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.."
    73         },
    74         { "", 0, NULL }
     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..."
     64        }
    7565};
    7666
     
    7969        int i;
    8070       
    81         for( i = 0; decrypt_tests[i].len; i++ )
     71        for( i = 0; clear_tests[i]; i++ )
    8272        {
    8373                tcase_fn_start (decrypt_tests[i].decrypted, __FILE__, __LINE__);
     
    8979               
    9080                fail_if( strcmp( decrypt_tests[i].decrypted, decrypted ) != 0,
    91                          "`%s' didn't decrypt properly", decrypt_tests[i].decrypted );
     81                         "%s didn't decrypt properly", clear_tests[i] );
    9282               
    9383                g_free( decrypted );
  • tests/check_help.c

    rb79308b r6cac643  
    77#include "help.h"
    88
    9 START_TEST(test_help_initfree)
     9START_TEST(test_help_none)
    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);
    1714END_TEST
    1815
     
    2825        TCase *tc_core = tcase_create("Core");
    2926        suite_add_tcase (s, tc_core);
    30         tcase_add_test (tc_core, test_help_initfree);
     27        tcase_add_test (tc_core, test_help_none);
    3128        tcase_add_test (tc_core, test_help_nonexistent);
    3229        return s;
  • tests/check_irc.c

    rb79308b r6cac643  
    3737        irc = irc_new(g_io_channel_unix_get_fd(ch1));
    3838
    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);
     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);
    4141        fail_unless(g_io_channel_flush(ch2, NULL) == G_IO_STATUS_NORMAL);
    4242
Note: See TracChangeset for help on using the changeset viewer.