Changeset 6738a67


Ignore:
Timestamp:
2008-07-16T23:22:52Z (11 years ago)
Author:
Sven Moritz Hallberg <pesco@…>
Branches:
master
Children:
9b55485
Parents:
9730d72 (diff), 6a78c0e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge in latest trunk

Files:
5 added
79 edited
2 moved

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r9730d72 r6738a67  
    1717*.gcno
    1818*.o
     19coverage
     20bitlbee.info
     21bitlbee.exe
  • Makefile

    r9730d72 r6738a67  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o otr.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o user.o
     12objects = account.o bitlbee.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o
    1313headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h otr.h query.h set.h sock.h storage.h user.h lib/events.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h
    1414subdirs = lib protocols
     15
     16ifeq ($(TARGET),i586-mingw32msvc)
     17objects += win32.o
     18LFLAGS+=-lws2_32
     19EFLAGS+=-lsecur32
     20OUTFILE=bitlbee.exe
     21else
     22objects += unix.o conf.o log.o otr.o
     23OUTFILE=bitlbee
     24endif
    1525
    1626# Expansion of variables
  • account.c

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

    r9730d72 r6738a67  
    5454        ;
    5555
    56         i = getaddrinfo( global.conf->iface, global.conf->port, &hints, &addrinfo_bind );
     56        i = getaddrinfo( global.conf->iface_in, global.conf->port, &hints, &addrinfo_bind );
    5757        if( i )
    5858        {
    5959                log_message( LOGLVL_ERROR, "Couldn't parse address `%s': %s",
    60                                            global.conf->iface, gai_strerror(i) );
     60                                           global.conf->iface_in, gai_strerror(i) );
    6161                return -1;
    6262        }
     
    118118       
    119119        if( global.conf->runmode == RUNMODE_FORKDAEMON )
    120                 ipc_master_load_state();
     120                ipc_master_load_state( getenv( "_BITLBEE_RESTART_STATE" ) );
    121121
    122122        if( global.conf->runmode == RUNMODE_DAEMON || global.conf->runmode == RUNMODE_FORKDAEMON )
    123123                ipc_master_listen_socket();
    124124       
     125#ifndef _WIN32
    125126        if( ( fp = fopen( global.conf->pidfile, "w" ) ) )
    126127        {
     
    132133                log_message( LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile );
    133134        }
     135#endif
    134136       
    135137        return( 0 );
     
    140142        if( !irc_new( 0 ) )
    141143                return( 1 );
    142        
    143         log_link( LOGLVL_ERROR, LOGOUTPUT_IRC );
    144         log_link( LOGLVL_WARNING, LOGOUTPUT_IRC );
    145144       
    146145        return( 0 );
     
    226225        if( st == size )
    227226        {
    228                 g_free( irc->sendbuffer );
    229                 irc->sendbuffer = NULL;
    230                 irc->w_watch_source_id = 0;
    231                
    232227                if( irc->status & USTATUS_SHUTDOWN )
     228                {
    233229                        irc_free( irc );
     230                }
     231                else
     232                {
     233                        g_free( irc->sendbuffer );
     234                        irc->sendbuffer = NULL;
     235                        irc->w_watch_source_id = 0;
     236                }
    234237               
    235238                return FALSE;
     
    250253        struct sockaddr_in conn_info;
    251254        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
    252         pid_t client_pid = 0;
    253255       
    254256        if( new_socket == -1 )
     
    258260        }
    259261       
     262#ifndef _WIN32
    260263        if( global.conf->runmode == RUNMODE_FORKDAEMON )
    261264        {
     265                pid_t client_pid = 0;
    262266                int fds[2];
    263267               
     
    316320        }
    317321        else
     322#endif
    318323        {
    319324                log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
  • bitlbee.conf

    r9730d72 r6738a67  
    1010##
    1111##  Inetd -- Run from inetd (default)
    12 ##  Daemon -- Run as a stand-alone daemon -- EXPERIMENTAL! BitlBee is not yet
    13 ##    stable enough to serve lots of users from one process. Because of this
    14 ##    and other reasons, the use of daemon-mode is *STRONGLY* discouraged,
    15 ##    don't even *think* of reporting bugs when you use this.
     12##  Daemon -- Run as a stand-alone daemon, serving all users from one process.
     13##    This saves memory if there are more users, the downside is that when one
     14##    user hits a crash-bug, all other users will also lose their connection.
    1615##  ForkDaemon -- Run as a stand-alone daemon, but keep all clients in separate
    1716##    child processes. This should be pretty safe and reliable to use instead
     
    3534# DaemonPort = 6667
    3635
     36## ClientInterface:
     37##
     38## If for any reason, you want BitlBee to use a specific address/interface
     39## for outgoing traffic (IM connections, HTTP(S), etc.), set it here.
     40##
     41# ClientInterface = 0.0.0.0
     42
    3743## AuthMode
    3844##
     
    4955##
    5056## Password the user should enter when logging into a closed BitlBee server.
     57## You can also have an MD5-encrypted password here. Format: "md5:", followed
     58## by a hash as generated for the <user password=""> attribute in a BitlBee
     59## XML file (for now there's no easier way to generate the hash).
    5160##
    5261# AuthPassword = ItllBeBitlBee   ## Heh.. Our slogan. ;-)
     62## or
     63# AuthPassword = md5:gzkK0Ox/1xh+1XTsQjXxBJ571Vgl
    5364
    5465## OperPassword
     
    5768##
    5869# OperPassword = ChangeMe!
     70## or
     71# OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX
    5972
    6073## HostName
  • bitlbee.h

    r9730d72 r6738a67  
    2929#define _GNU_SOURCE /* Stupid GNU :-P */
    3030
     31/* Depend on Windows 2000 for now since we need getaddrinfo() */
     32#define _WIN32_WINNT 0x0501
     33
    3134#define PACKAGE "BitlBee"
    32 #define BITLBEE_VERSION "1.1.1dev"
     35#define BITLBEE_VERSION "1.2.1"
    3336#define VERSION BITLBEE_VERSION
    3437
    35 #define MAX_STRING 128
     38#define MAX_STRING 511
    3639
    3740#if HAVE_CONFIG_H
     
    4851#include <stdio.h>
    4952#include <ctype.h>
     53#include <errno.h>
     54
    5055#ifndef _WIN32
    5156#include <syslog.h>
    52 #include <errno.h>
    5357#endif
    5458
     
    9498#undef g_main_quit
    9599#define g_main_quit             __PLEASE_USE_B_MAIN_QUIT__
    96 
    97 #ifndef F_OK
    98 #define F_OK 0
    99 #endif
    100100
    101101#ifndef G_GNUC_MALLOC
     
    162162gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond );
    163163
     164char *set_eval_root_nick( set_t *set, char *new_nick );
     165
    164166extern global_t global;
    165167
  • conf.c

    r9730d72 r6738a67  
    4545        conf = g_new0( conf_t, 1 );
    4646       
    47         conf->iface = NULL;
     47        conf->iface_in = NULL;
     48        conf->iface_out = NULL;
    4849        conf->port = g_strdup( "6667" );
    4950        conf->nofork = 0;
     
    7879        }
    7980       
    80         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
     81        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hu:" ) ) >= 0 )
    8182        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
    8283        {
    8384                if( opt == 'i' )
    8485                {
    85                         conf->iface = g_strdup( optarg );
     86                        conf->iface_in = g_strdup( optarg );
    8687                }
    8788                else if( opt == 'p' )
     
    132133                                "\n"
    133134                                "  -I  Classic/InetD mode. (Default)\n"
    134                                 "  -D  Daemon mode. (Still EXPERIMENTAL!)\n"
     135                                "  -D  Daemon mode. (one process serves all)\n"
    135136                                "  -F  Forking daemon. (one process per client)\n"
    136137                                "  -u  Run daemon as specified user.\n"
     
    146147                        return NULL;
    147148                }
    148                 else if( opt == 'R' )
    149                 {
    150                         /* We can't load the statefile yet (and should make very sure we do this
    151                            only once), so set the filename here and load the state information
    152                            when initializing ForkDaemon. (This option only makes sense in that
    153                            mode anyway!) */
    154                         ipc_master_set_statefile( optarg );
    155                 }
    156149                else if( opt == 'u' )
    157150                {
     
    203196                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
    204197                        {
    205                                 g_free( conf->iface );
    206                                 conf->iface = g_strdup( ini->value );
     198                                g_free( conf->iface_in );
     199                                conf->iface_in = g_strdup( ini->value );
    207200                        }
    208201                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
     
    210203                                g_free( conf->port );
    211204                                conf->port = g_strdup( ini->value );
     205                        }
     206                        else if( g_strcasecmp( ini->key, "clientinterface" ) == 0 )
     207                        {
     208                                g_free( conf->iface_out );
     209                                conf->iface_out = g_strdup( ini->value );
    212210                        }
    213211                        else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
     
    258256                        {
    259257                                g_strfreev( conf->migrate_storage );
    260                                 conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
     258                                conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 );
    261259                        }
    262260                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
  • conf.h

    r9730d72 r6738a67  
    3232typedef struct conf
    3333{
    34         char *iface;
     34        char *iface_in, *iface_out;
    3535        char *port;
    3636        int nofork;
  • configure

    r9730d72 r6738a67  
    2020ipcsocket='/var/run/bitlbee.sock'
    2121pcdir='$prefix/lib/pkgconfig'
     22systemlibdirs="/lib /usr/lib /usr/local/lib"
    2223
    2324msn=1
     
    7677--ssl=...       SSL library to use (gnutls, nss, openssl, bogus, auto)
    7778                                                        $ssl
     79
     80--target=...    Cross compilation target                same as host
    7881EOF
    7982                exit;
     
    109112PCDIR=$pcdir
    110113
     114TARGET=$target
    111115ARCH=$arch
    112116CPU=$cpu
    113 OUTFILE=bitlbee
    114117
    115118DESTDIR=
     
    134137EOF
    135138
     139
     140
     141if [ -n "$target" ]; then
     142        PKG_CONFIG_LIBDIR=/usr/$target/lib/pkgconfig
     143        export PKG_CONFIG_LIBDIR
     144        PATH=/usr/$target/bin:$PATH
     145        CC=$target-cc
     146        LD=$target-ld
     147        systemlibdirs="/usr/$target/lib"
     148fi
     149
     150
    136151if [ "$debug" = "1" ]; then
    137152        [ -z "$CFLAGS" ] && CFLAGS=-g
     
    160175echo "CC=$CC" >> Makefile.settings;
    161176
    162 if [ -n "$LD" ]; then
    163         echo "LD=$LD" >> Makefile.settings;
    164 elif type ld > /dev/null 2> /dev/null; then
    165         echo "LD=ld" >> Makefile.settings;
    166 else
    167         echo 'Cannot find ld, aborting.'
    168         exit 1;
    169 fi
     177if [ -z "$LD" ]; then
     178        if type ld > /dev/null 2> /dev/null; then
     179                LD=ld
     180        else
     181                echo 'Cannot find ld, aborting.'
     182                exit 1;
     183        fi
     184fi
     185
     186echo "LD=$LD" >> Makefile.settings
    170187
    171188if [ -z "$PKG_CONFIG" ]; then
     
    215232detect_gnutls()
    216233{
    217         if libgnutls-config --version > /dev/null 2> /dev/null; then
     234        if $PKG_CONFIG --exists gnutls; then
     235                cat <<EOF>>Makefile.settings
     236EFLAGS+=`$PKG_CONFIG --libs gnutls`
     237CFLAGS+=`$PKG_CONFIG --cflags gnutls`
     238EOF
     239                ssl=gnutls
     240                ret=1
     241        elif libgnutls-config --version > /dev/null 2> /dev/null; then
    218242                cat <<EOF>>Makefile.settings
    219243EFLAGS+=`libgnutls-config --libs`
     
    269293elif [ "$ssl" = "nss" ]; then
    270294        detect_nss
     295elif [ "$ssl" = "sspi" ]; then
     296        echo
    271297elif [ "$ssl" = "openssl" ]; then
    272298        echo
     
    325351echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
    326352
    327 for i in /lib /usr/lib /usr/local/lib; do
     353for i in $systemlibdirs; do
    328354        if [ -f $i/libresolv.a ]; then
    329355                echo '#define HAVE_RESOLV_A' >> config.h
     
    377403
    378404if [ "$gcov" = "1" ]; then
    379         echo "CFLAGS+=-ftest-coverage -fprofile-arcs" >> Makefile.settings
    380         echo "EFLAGS+=-lgcov" >> Makefile.settings
     405        echo "CFLAGS+=--coverage" >> Makefile.settings
     406        echo "EFLAGS+=--coverage" >> Makefile.settings
    381407fi
    382408
     
    387413fi
    388414
     415otrprefix=""
     416for i in / /usr /usr/local; do
     417        if [ -f ${i}/lib/libotr.a ]; then
     418                otrprefix=${i}
     419                break
     420        fi
     421done
    389422if [ "$otr" = "auto" ]; then
    390         for i in /lib /usr/lib /usr/local/lib; do
    391                 if [ -f $i/libotr.a ]; then
    392                         otr=1
    393                         break
    394                 fi
    395         done
    396 fi
    397 if [ "$otr" = 0 ]; then
     423        if [ -n "$otrprefix" ]; then
     424                otr=1
     425        else
     426                otr=0
     427        fi
     428fi
     429if [ "$otr" = 1 ]; then
     430        echo '#define WITH_OTR' >> config.h
     431        echo "EFLAGS+=-L${otrprefix}/lib -lotr" >> Makefile.settings
     432        echo "CFLAGS+=-I${otrprefix}/include" >> Makefile.settings
     433else
    398434        echo '#undef WITH_OTR' >> config.h
    399 else
    400         echo '#define WITH_OTR' >> config.h
    401         echo "EFLAGS+=-lotr" >> Makefile.settings
    402435fi
    403436
     
    500533        echo 'Cygwin is not officially supported.'
    501534;;
     535Windows )
     536;;
    502537* )
    503538        echo 'We haven'\''t tested BitlBee on many platforms yet, yours is untested. YMMV.'
     
    506541esac
    507542
     543if [ -n "$target" ]; then
     544        echo "Cross-compiling for: $target"
     545fi
     546
    508547echo
    509548echo 'Configuration done:'
  • debian/README.Debian

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

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

    r9730d72 r6738a67  
    1 bitlbee (1.1.1dev-0pre) unstable; urgency=low
    2 
     1bitlbee (1.2-6) UNRELEASED; urgency=low
     2
     3  * Add Homepage and Vcs-Bzr fields.
     4
     5 -- Jelmer Vernooij <jelmer@samba.org>  Sun, 11 May 2008 14:18:16 +0200
     6
     7bitlbee (1.2-5) unstable; urgency=low
     8
     9  * Add myself to uploaders.
     10  * Bump standards version to 3.8.0.
     11  * Fix FSF address.
     12  * Avoid changing uid from init script. (Closes: #474589)
     13
     14 -- Jelmer Vernooij <jelmer@samba.org>  Mon, 16 Jun 2008 00:53:20 +0200
     15
     16bitlbee (1.2-4) unstable; urgency=low
     17
     18  * Fixed init script to use the BITLBEE_OPTS variable, not an undefined
     19    DAEMON_OPT. (Closes: #474583)
     20  * Added dependency information to the init script. (Closes: #472567)
     21  * Added bitlbee-dev package. Patch from RISKO Gergely <risko@debian.org>
     22    with some small modifications. (Closes: #473480)
     23
     24 -- Wilmer van der Gaast <wilmer@gaast.net>  Wed, 07 May 2008 22:40:40 -0700
     25
     26bitlbee (1.2-3) unstable; urgency=low
     27
     28  * Removed DEB_BUILD_OPTIONS again (forgot to apply that change to the 1.2
     29    branch when I finished 1.0.4-2, things diverged too much anyway.)
     30    Closes: #472540.
     31
     32 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 24 Mar 2008 21:10:14 +0000
     33
     34bitlbee (1.2-2) unstable; urgency=low
     35
     36  * Fixed some packaging issues reported by IRC and e-mail. (Closes: #472373)
     37  * Fixed proxy support. (Closes: #472395)
     38  * Added a BitlBee group so only root can edit the configs and BitlBee can
     39    just *read* it.
     40  * Manually deleting /var/lib/bitlbee/ when purging, deluser doesn't want to
     41    do it.
     42
     43 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 24 Mar 2008 19:48:24 +0000
     44
     45bitlbee (1.2-1) unstable; urgency=low
     46
     47  * New upstream release. (Closes: #325017, #386914, #437515)
     48  * With hopefully completely sane charset handling (Closes: #296145)
    349  * Switched to the new forking daemon mode. Added /etc/default/bitlbee
    450    file, an init script. People who want to stick with inetd can do so, see
    551    the defaults file.
     52    (Closes: #460741, #466171, #294585, #345038, #306452, #392682)
    653  * Got rid of debconf Woody compatibility stuff.
    754  * No more MPL code in BitlBee, thanks to the Jabber module rewrite!
    8 
    9  -- Wilmer van der Gaast <wilmer@gaast.net>  Fri, 06 Jul 2007 09:09:36 +0100
     55  * Added Italian translation, sorry for taking so long! (Closes: #448238)
     56  * Added libevent dependency (more reliable event handling).
     57  * Removed GLib 1.x dependency because BitlBee really requires GLib >=2.4.
     58
     59 -- Wilmer van der Gaast <wilmer@gaast.net>  Tue, 18 Mar 2008 23:44:19 +0000
     60
     61bitlbee (1.0.4-2) unstable; urgency=low
     62
     63  * Removed $DEB_BUILD_OPTIONS because apparently buildds fill it with crap.
     64    (Closes: #458717)
     65
     66 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 11 Feb 2008 19:15:33 +0000
     67
     68bitlbee (1.0.4-1) unstable; urgency=low
     69
     70  * New upstream release.
     71  * Changed libnss-dev dependency. (Closes: #370442)
     72  * Added build-indep rule to debian/rules. (Closes: #395673)
     73
     74 -- Wilmer van der Gaast <wilmer@gaast.net>  Wed, 29 Aug 2007 20:24:28 +0100
    1075
    1176bitlbee (1.0.3-1.3) unstable; urgency=low
  • debian/conffiles

    r9730d72 r6738a67  
    11/etc/bitlbee/motd.txt
    22/etc/bitlbee/bitlbee.conf
     3/etc/init.d/bitlbee
  • debian/control

    r9730d72 r6738a67  
    33Priority: optional
    44Maintainer: Wilmer van der Gaast <wilmer@gaast.net>
    5 Standards-Version: 3.5.9
    6 Build-Depends: libglib2.0-dev | libglib-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf
     5Uploaders: Jelmer Vernooij <jelmer@samba.org>
     6Standards-Version: 3.8.0
     7Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf
     8Homepage: http://www.bitlbee.org/
     9Vcs-Bzr: http://code.bitlbee.org/bitlbee/
     10DM-Upload-Allowed: yes
    711
    812Package: bitlbee
     
    1216 This program can be used as an IRC server which forwards everything you
    1317 say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo.
     18
     19Package: bitlbee-dev
     20Architecture: all
     21Depends: bitlbee (= ${binary:Version})
     22Description: An IRC to other chat networks gateway
     23 This program can be used as an IRC server which forwards everything you
     24 say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo.
     25 .
     26 This package holds development stuff for compiling plug-ins.
  • debian/copyright

    r9730d72 r6738a67  
    2626  You should have received a copy of the GNU General Public License with
    2727  the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL;
    28   if not, write to the Free Software Foundation, Inc., 59 Temple Place,
    29   Suite 330, Boston, MA  02111-1307  USA
     28  if not, write to the Free Software Foundation, Inc., 51 Franklin St,
     29  Fifth Floor, Boston, MA 02110-1301, USA.
    3030============================================================================
    3131
     
    4040
    4141 Copyright (C) 2000  Free Software Foundation, Inc.
    42      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     42        51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    4343 Everyone is permitted to copy and distribute verbatim copies
    4444 of this license document, but changing it is not allowed.
  • debian/postinst

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

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

    r9730d72 r6738a67  
    33DEBUG ?= 0
    44
     5ifdef BITLBEE_VERSION
     6BITLBEE_FORCE_VERSION=1
     7else
    58# Want to use the full package version number instead of just the release.
    69BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')"
    710export BITLBEE_VERSION
    8 
     11endif
    912
    1013build-arch: build-arch-stamp
    1114build-arch-stamp:
    12         if [ ! -d debian ]; then exit 1; fi
    13         ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee $(DEB_BUILD_OPTIONS)
     15        [ -d debian ]
     16        ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent
    1417        $(MAKE)
    1518#       $(MAKE) -C doc/ all
     
    1720
    1821clean:
    19         if [ "`whoami`" != "root" -o ! -d debian ]; then exit 1; fi
    20         rm -rf build-arch-stamp debian/bitlbee debian/*.substvars debian/files
    21         -$(MAKE) distclean
     22        [ "`whoami`" = "root" -a -d debian ]
     23        rm -rf build-arch-stamp debian/bitlbee debian/*.substvars debian/files debian/bitlbee-dev
     24        $(MAKE) distclean
    2225#       -$(MAKE) -C doc/ clean
    2326                               
    2427
    2528install-arch: build-arch
    26         if [ "`whoami`" != "root" -o ! -d debian ]; then exit 1; fi
     29        [ "`whoami`" = "root" -a -d debian ]
    2730        mkdir -p debian/bitlbee/DEBIAN/
    2831        $(MAKE) install install-etc DESTDIR=`pwd`/debian/bitlbee
     
    3235        cp doc/user-guide/user-guide.html debian/bitlbee/usr/share/doc/bitlbee/
    3336
     37install-indep: install-arch
     38        [ "`whoami`" = "root" -a -d debian ]
     39        mkdir -p debian/bitlbee-dev/DEBIAN/
     40        $(MAKE) install-dev DESTDIR=`pwd`/debian/bitlbee-dev
     41
     42        mkdir -p debian/bitlbee-dev/usr/share/doc/bitlbee-dev/
     43
    3444binary-arch: build-arch install-arch
    35         if [ "`whoami`" != "root" -o ! -d debian ]; then exit 1; fi
     45        [ "`whoami`" = "root" -a -d debian ]
    3646
    3747        chmod 755 debian/post* debian/pre* debian/config debian/bitlbee.init
     
    4959                        doc/bitlbee/examples/* man/man8/bitlbee.8 man/man5/bitlbee.conf.5
    5060       
    51         chown -R root.root debian/bitlbee/
     61        chown -R root:root debian/bitlbee/
    5262        find debian/bitlbee/usr/share/ -type d -exec chmod 755 {} \;
    5363        find debian/bitlbee/usr/share/ -type f -exec chmod 644 {} \;
     
    6676                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
    6777        dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee
    68 ifdef BITLBEE_VERSION
     78ifdef BITLBEE_FORCE_VERSION
    6979        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'
    7080else
     
    7484        dpkg --build debian/bitlbee ..
    7585
    76 debug-build:
    77         BITLBEE_VERSION=\"`date +%Y%m%d`-`hostname`-debug\" debian/rules clean binary DEBUG=1
     86binary-indep: install-indep
     87        [ "`whoami`" = "root" -a -d debian ]
    7888
    79 binary: binary-arch
     89        chown -R root.root debian/bitlbee-dev/
     90        find debian/bitlbee-dev/usr/share/ -type d -exec chmod 755 {} \;
     91        find debian/bitlbee-dev/usr/share/ -type f -exec chmod 644 {} \;
     92
     93        cp debian/changelog debian/bitlbee-dev/usr/share/doc/bitlbee-dev/changelog.Debian
     94        gzip -9 debian/bitlbee-dev/usr/share/doc/bitlbee-dev/changelog.Debian
     95        cp debian/copyright debian/bitlbee-dev/usr/share/doc/bitlbee-dev/copyright
     96
     97        cd debian/bitlbee-dev; \
     98                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
     99
     100        dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev
     101
     102        dpkg --build debian/bitlbee-dev ..
     103
     104binary: binary-arch binary-indep
    80105build: build-arch
    81 install: install-arch
     106install: install-arch install-indep
    82107
    83 .PHONY: build-arch build clean binary-arch binary install-arch install
     108.PHONY: build-arch build clean binary-arch binary install-arch install binary-indep install-indep
  • doc/CHANGES

    r9730d72 r6738a67  
     1This ChangeLog mostly lists changes relevant to users. A full log can be
     2found in the bzr commit logs, for example you can try:
     3
     4http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
     5
     6Version 1.2.1:
     7- Fixed proxy support.
     8- Fixed stalling issues while connecting to Jabber when using the OpenSSL
     9  module.
     10- Fixed problem with GLib and ForkDaemon where processes didn't die when
     11  the client disconnects.
     12- Fixed handling of "set charset none". (Which pretty much breaks the account
     13  completely in 1.2.)
     14- You can now automatically identify yourself to BitlBee by setting a server
     15  password in your IRC client.
     16- Compatible with all crazy kinds of line endings that clients can send.
     17- Changed root nicknames are now saved.
     18- Added ClientInterface setting to bind() outgoing connections to a specific
     19  network interface.
     20- Support for receiving Jabber chatroom invitations.
     21- Relaxed port restriction of the Jabber module: added ports 80 and 443.
     22- Preserving case in Jabber resources of buddies, since these should
     23  officially be treated as case sensitive.
     24- Fully stripping spaces from AIM screennames, this didn't happen completely
     25  which severly breaks the IRC protocol.
     26- Removed all the yellow tape around daemon mode, it's pretty mature by now:
     27  testing.bitlbee.org serves all (~30) SSL users from one daemon mode
     28  process without any serious stability issues.
     29- Fixed GLib <2.6 compatibility issue.
     30- Misc. memory leak/crash fixes.
     31
     32Finished 24 Jun 2008
     33
    134Version 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.
    535- Added ForkDaemon mode next to the existing Daemon- and inetd modes. With
    636  ForkDaemon you can run BitlBee as a stand-alone daemon and every connection
     
    2151  1.x is so old that supporting it really isn't necessary anymore.
    2252- Many, many, MANY little changes, improvements, fixes. Using non-blocking
    23   I/O as much as possible, fixed lots of little bugs (including bugs that
    24   affected daemon mode stability). See the bzr logs for more information.
    25 - Added units tests, will have to add some more before the real release.
     53  I/O as much as possible, replaced the Gaim (0.59, IOW heavily outdated)
     54  API, fixed lots of little bugs (including bugs that affected daemon mode
     55  stability). See the bzr logs for more information.
     56- One of the user-visible changes from the API change: You can finally see
     57  all away states/messages properly.
     58- Added units tests. Test coverage is very minimal for now.
     59- Better charset handling: Everything is just converted from/to UTF-8 right
     60  in the IRC core, and charset mismatches are detected (if possible) and the
     61  user is asked to resolve this before continuing. Also, UTF-8 is the default
     62  setting now, since that's how the world seems to work these days.
     63- One can now keep hashed passwords in bitlbee.conf instead of the cleartext
     64  version.
    2665- Most important change: New file format for user data (accounts, nicks and
    2766  settings). Migration to the new format should happen transparently,
     
    69108  * An XML console (add xmlconsole to your contact list or see "help set
    70109    xmlconsole" if you want it permanently).
    71 
    72 Finished ???
     110- The Yahoo! module now says it supports YMSG protocol version 12, which will
     111  hopefully keep the Yahoo module working after 2008-04-02 (when Yahoo! is
     112  dropping support for version 6.x of their client).
     113- MSN switchboard handling changes. Hopefully less messages will get lost now,
     114  although things are still not perfect.
     115
     116Finished 17 Mar 2008
    73117
    74118Version 1.0.4:
  • doc/README

    r9730d72 r6738a67  
    4141by default) and chown it to the UID BitlBee is running as. Make sure this
    4242directory is read-/writable by this user only.
     43
     44--- (Fork)Daemon mode
     45
     46If you don't want to run any inetd daemon, you can run BitlBee in Daemon
     47mode. Right now, daemon mode may be a bad idea on servers with multiple
     48users, since possible fatal BitlBee bugs will crash the BitlBee process and
     49disconnect all connected users at once. Instead, you can use ForkDaemon
     50mode, which serves every user from a separate process, without depending on
     51an inetd daemon.
     52
     53To use BitlBee in daemon mode, just start it with the right flags or enable
     54it in bitlbee.conf. You probably want to write an init script to start
     55BitlBee automatically after a reboot. (This is where you realise using
     56a package from your distro would've been a better idea. :-P)
     57
     58Note that the BitlBee code is getting stable enough for daemon mode to be
     59useful. Some public servers use it, and it saves a lot of memory by serving
     60tens of users from a single process. One crash affects all users, but these
     61are becoming quite rare.
    4362
    4463
     
    88107versions of make, we'd love to hear it, but it seems this just isn't
    89108possible.
    90 
    91 
    92 RUNNING ON SERVERS WITH MANY USERS
    93 ==================================
    94 
    95 BitlBee is not yet bug-free. Sometimes a bug causes the program to get into
    96 an infinite loop. Something you really don't want on a public server,
    97 especially when that machine is also used for other (mission-critical) things.
    98 For now we can't do much about it. We haven't seen that happen for a long
    99 time already on our own machines, but some people still manage to get
    100 themselves in nasty situations we haven't seen before.
    101 
    102 For now the best we can offer against this problem is bitlbeed, which allows
    103 you to setrlimit() the child processes to use no more than a specified
    104 number of CPU seconds. Not the best solution (not really a solution anyway),
    105 but certainly trashing one busy daemon process is better than trashing your
    106 whole machine.
    107 
    108 We don't believe adding a limit for bitlbee to /etc/security/limits.conf will
    109 work, because that file is only read by PAM (ie just for real login users,
    110 not daemons).
    111 
    112 See utils/bitlbeed.c for more information about the program.
    113 
    114 Just a little note: Now that we reach version 1.0, this shouldn't be that
    115 much of an issue anymore. However, on a public server, especially if you
    116 also use it for other things, it can't hurt to protect yourself against
    117 possible problems.
    118109
    119110
  • doc/bitlbee.8

    r9730d72 r6738a67  
    4444
    4545\fBbitlbee\fP should be called by
    46 .BR inetd (8).
    47 (Or \fBbitlbeed\fP,
    48 if you can't run and/or configure \fBinetd\fP.) There is an experimental
    49 daemon mode too, in which BitlBee will serve all clients in one process
    50 (and does not require inetd), but this mode is still experimental.
    51 There are still some bugs left in BitlBee, and if they cause a crash,
    52 that would terminate the BitlBee connection for all clients.
     46.BR inetd (8),
     47or you can run it as a stand-alone daemon.
    5348.PP
    5449.SH OPTIONS
     
    6257Run in daemon mode. In this mode, BitlBee forks to the background and
    6358waits for new connections. All clients will be served from one process.
    64 This is still experimental. See the note above for more information.
    6559.IP "-F"
    6660Run in ForkDaemon mode. This is similar to ordinary daemon mode, but every
    67 client gets its own process. Easier to set up than inetd mode, but without
     61client gets its own process. Easier to set up than inetd mode, and without
    6862the possible stability issues.
    6963.IP "-i \fIaddress\fP"
  • doc/user-guide/Support.xml

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

    r9730d72 r6738a67  
    163163
    164164                        <para>
    165                                 If you want, you can also tell BitlBee what nick to give the new contact. Of course you can also use the <emphasis>rename</emphasis> command for that, but sometimes this might be more convenient.
    166                         </para>
    167                        
    168                         <para>
    169                                 Adding -tmp adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list.
     165                                If you want, you can also tell BitlBee what nick to give the new contact. The -tmp option adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. This normally won't show you any presence notifications.
    170166                        </para>
    171167                </description>
     
    532528
    533529        <bitlbee-setting name="charset" type="string" scope="global">
    534                 <default>iso8859-1</default>
     530                <default>utf-8</default>
    535531                <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values>
    536532
    537533                <description>
    538534                        <para>
    539                                 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.
    540                         </para>
    541 
    542                         <para>
    543                                 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
     535                                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.
     536                        </para>
     537
     538                        <para>
     539                                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
    544540                        </para>
    545541                </description>
     
    804800        </bitlbee-setting>
    805801
     802        <bitlbee-setting name="root_nick" type="string" scope="global">
     803                <default>root</default>
     804
     805                <description>
     806                        <para>
     807                                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.
     808                        </para>
     809                </description>
     810        </bitlbee-setting>
     811
    806812        <bitlbee-setting name="save_on_quit" type="boolean" scope="global">
    807813                <default>true</default>
     
    888894                <description>
    889895                        <para>
    890                                 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. ;-)
     896                                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.
    891897                        </para>
    892898                </description>
     
    10571063                <short-description>Change friendly name, nick</short-description>
    10581064                <syntax>nick &lt;connection&gt; [&lt;new nick&gt;]</syntax>
    1059                 <syntax>nick</syntax>
    1060 
    1061                 <description>
    1062                         <para>
    1063                                 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.
    1064                         </para>
    1065 
    1066                         <para>
    1067                                 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.
     1065                <syntax>nick &lt;connection&gt;</syntax>
     1066
     1067                <description>
     1068                        <para>
     1069                                Deprecated: Use the per-account <emphasis>display_name</emphasis> setting to read and change this information.
    10681070                        </para>
    10691071                </description>
    10701072
    10711073                <ircexample>
    1072                         <ircline nick="wouter">nick 1 "Wouter Paesen"</ircline>
    1073                         <ircline nick="root">Setting your name on connection 1 to `Wouter Paesen'</ircline>
     1074                        <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline>
     1075                        <ircline nick="root">display_name = `The majestik møøse'</ircline>
    10741076                </ircexample>
    10751077
  • doc/user-guide/misc.xml

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

    r9730d72 r6738a67  
    6161
    6262<para>
    63 For most protocols (currently MSN, Jabber, Yahoo and AOL) BitlBee can download the contact list automatically from the IM server and all the on-line users should appear in the control channel when you log in.
     63Now BitlBee logs in and downloads the contact list from the IM server. In a few seconds, all your on-line buddies should show up in the control channel.
    6464</para>
    6565
    6666<para>
    67 BitlBee will convert names into irc-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo.
     67BitlBee will convert names into IRC-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo.
    6868</para>
    6969
     
    127127<ircexample>
    128128        <ircline nick="you">tux: hey, how's the weather down there?</ircline>
    129         <ircline nick="tux"> you: a bit chilly!</ircline>
     129        <ircline nick="tux">you: a bit chilly!</ircline>
    130130</ircexample>
    131131
    132132<para>
    133 If you'd rather chat with them in a separate window use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like you would for a private message in IRC.  If you want to have messages automatically come up in private messages rather than in the &amp;bitlbee channel, use the <emphasis>set private</emphasis> command: <emphasis>set private true</emphasis> (<emphasis>set private false</emphasis> to change back).
     133Note that, although all contacts are in the &amp;bitlbee channel, only tux will actually receive this message. The &amp;bitlbee channel shouldn't be confused with a real IRC channel.
     134</para>
     135
     136<para>
     137If you prefer chatting in a separate window, use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like on real IRC. BitlBee will remember how you talk to someone and show his/her responses the same way. If you want to change the default behaviour (for people you haven't talked to yet), see <emphasis>help set private</emphasis>.
    134138</para>
    135139
  • ipc.c

    r9730d72 r6738a67  
    3333
    3434GSList *child_list = NULL;
    35 static char *statefile = NULL;
    3635
    3736static void ipc_master_cmd_client( irc_t *data, char **cmd )
     
    6362}
    6463
     64static void ipc_master_cmd_deaf( irc_t *data, char **cmd )
     65{
     66        if( global.conf->runmode == RUNMODE_DAEMON )
     67        {
     68                b_event_remove( global.listen_watch_source_id );
     69                close( global.listen_socket );
     70               
     71                global.listen_socket = global.listen_watch_source_id = -1;
     72       
     73                ipc_to_children_str( "OPERMSG :Closed listening socket, waiting "
     74                                     "for all users to disconnect." );
     75        }
     76        else
     77        {
     78                ipc_to_children_str( "OPERMSG :The DEAF command only works in "
     79                                     "normal daemon mode. Try DIE instead." );
     80        }
     81}
     82
    6583void ipc_master_cmd_rehash( irc_t *data, char **cmd )
    6684{
     
    98116        { "hello",      0, ipc_master_cmd_client,     0 },
    99117        { "die",        0, ipc_master_cmd_die,        0 },
     118        { "deaf",       0, ipc_master_cmd_deaf,       0 },
    100119        { "wallops",    1, NULL,                      IPC_CMD_TO_CHILDREN },
    101120        { "wall",       1, NULL,                      IPC_CMD_TO_CHILDREN },
     
    209228}
    210229
     230/* Return just one line. Returns NULL if something broke, an empty string
     231   on temporary "errors" (EAGAIN and friends). */
    211232static char *ipc_readline( int fd )
    212233{
    213         char *buf, *eol;
     234        char buf[513], *eol;
    214235        int size;
    215        
    216         buf = g_new0( char, 513 );
    217236       
    218237        /* Because this is internal communication, it should be pretty safe
     
    221240           sockets and limites message length, messages should always be
    222241           complete. Saves us quite a lot of code and buffering. */
    223         size = recv( fd, buf, 512, MSG_PEEK );
     242        size = recv( fd, buf, sizeof( buf ) - 1, MSG_PEEK );
    224243        if( size == 0 || ( size < 0 && !sockerr_again() ) )
    225244                return NULL;
     
    229248                buf[size] = 0;
    230249       
    231         eol = strstr( buf, "\r\n" );
    232         if( eol == NULL )
     250        if( ( eol = strstr( buf, "\r\n" ) ) == NULL )
    233251                return NULL;
    234252        else
    235253                size = eol - buf + 2;
    236        
    237         g_free( buf );
    238         buf = g_new0( char, size + 1 );
    239254       
    240255        if( recv( fd, buf, size, 0 ) != size )
    241256                return NULL;
    242257        else
    243                 buf[size-2] = 0;
    244        
    245         return buf;
     258                return g_strndup( buf, size - 2 );
    246259}
    247260
     
    254267                cmd = irc_parse_line( buf );
    255268                if( cmd )
     269                {
    256270                        ipc_command_exec( data, cmd, ipc_master_commands );
    257         }
    258         else
     271                        g_free( cmd );
     272                }
     273                g_free( buf );
     274        }
     275        else
     276        {
     277                ipc_master_free_fd( source );
     278        }
     279       
     280        return TRUE;
     281}
     282
     283gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )
     284{
     285        char *buf, **cmd;
     286       
     287        if( ( buf = ipc_readline( source ) ) )
     288        {
     289                cmd = irc_parse_line( buf );
     290                if( cmd )
     291                {
     292                        ipc_command_exec( data, cmd, ipc_child_commands );
     293                        g_free( cmd );
     294                }
     295                g_free( buf );
     296        }
     297        else
     298        {
     299                ipc_child_disable();
     300        }
     301       
     302        return TRUE;
     303}
     304
     305void ipc_to_master( char **cmd )
     306{
     307        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     308        {
     309                char *s = irc_build_line( cmd );
     310                ipc_to_master_str( "%s", s );
     311                g_free( s );
     312        }
     313        else if( global.conf->runmode == RUNMODE_DAEMON )
     314        {
     315                ipc_command_exec( NULL, cmd, ipc_master_commands );
     316        }
     317}
     318
     319void ipc_to_master_str( char *format, ... )
     320{
     321        char *msg_buf;
     322        va_list params;
     323
     324        va_start( params, format );
     325        msg_buf = g_strdup_vprintf( format, params );
     326        va_end( params );
     327       
     328        if( strlen( msg_buf ) > 512 )
     329        {
     330                /* Don't send it, it's too long... */
     331        }
     332        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
     333        {
     334                if( global.listen_socket >= 0 )
     335                        if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 )
     336                                ipc_child_disable();
     337        }
     338        else if( global.conf->runmode == RUNMODE_DAEMON )
     339        {
     340                char **cmd, *s;
     341               
     342                if( ( s = strchr( msg_buf, '\r' ) ) )
     343                        *s = 0;
     344               
     345                cmd = irc_parse_line( msg_buf );
     346                ipc_command_exec( NULL, cmd, ipc_master_commands );
     347                g_free( cmd );
     348        }
     349       
     350        g_free( msg_buf );
     351}
     352
     353void ipc_to_children( char **cmd )
     354{
     355        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     356        {
     357                char *msg_buf = irc_build_line( cmd );
     358                ipc_to_children_str( "%s", msg_buf );
     359                g_free( msg_buf );
     360        }
     361        else if( global.conf->runmode == RUNMODE_DAEMON )
    259362        {
    260363                GSList *l;
    261                 struct bitlbee_child *c;
    262                
    263                 for( l = child_list; l; l = l->next )
     364               
     365                for( l = irc_connection_list; l; l = l->next )
     366                        ipc_command_exec( l->data, cmd, ipc_child_commands );
     367        }
     368}
     369
     370void ipc_to_children_str( char *format, ... )
     371{
     372        char *msg_buf;
     373        va_list params;
     374
     375        va_start( params, format );
     376        msg_buf = g_strdup_vprintf( format, params );
     377        va_end( params );
     378       
     379        if( strlen( msg_buf ) > 512 )
     380        {
     381                /* Don't send it, it's too long... */
     382        }
     383        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
     384        {
     385                int msg_len = strlen( msg_buf );
     386                GSList *l, *next;
     387               
     388                for( l = child_list; l; l = next )
    264389                {
    265                         c = l->data;
    266                         if( c->ipc_fd == source )
     390                        struct bitlbee_child *c = l->data;
     391                       
     392                        next = l->next;
     393                        if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 )
    267394                        {
    268395                                ipc_master_free_one( c );
    269396                                child_list = g_slist_remove( child_list, c );
    270                                 break;
    271397                        }
    272                 }
    273         }
    274        
    275         return TRUE;
    276 }
    277 
    278 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )
    279 {
    280         char *buf, **cmd;
    281        
    282         if( ( buf = ipc_readline( source ) ) )
    283         {
    284                 cmd = irc_parse_line( buf );
    285                 if( cmd )
    286                         ipc_command_exec( data, cmd, ipc_child_commands );
    287         }
    288         else
    289         {
    290                 b_event_remove( global.listen_watch_source_id );
    291                 close( global.listen_socket );
    292                
    293                 global.listen_socket = -1;
    294         }
    295        
    296         return TRUE;
    297 }
    298 
    299 void ipc_to_master( char **cmd )
    300 {
    301         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    302         {
    303                 char *s = irc_build_line( cmd );
    304                 ipc_to_master_str( "%s", s );
    305                 g_free( s );
    306         }
    307         else if( global.conf->runmode == RUNMODE_DAEMON )
    308         {
    309                 ipc_command_exec( NULL, cmd, ipc_master_commands );
    310         }
    311 }
    312 
    313 void ipc_to_master_str( char *format, ... )
    314 {
    315         char *msg_buf;
    316         va_list params;
    317 
    318         va_start( params, format );
    319         msg_buf = g_strdup_vprintf( format, params );
    320         va_end( params );
    321        
    322         if( strlen( msg_buf ) > 512 )
    323         {
    324                 /* Don't send it, it's too long... */
    325         }
    326         else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    327         {
    328                 write( global.listen_socket, msg_buf, strlen( msg_buf ) );
    329         }
    330         else if( global.conf->runmode == RUNMODE_DAEMON )
    331         {
    332                 char **cmd, *s;
    333                
    334                 if( ( s = strchr( msg_buf, '\r' ) ) )
    335                         *s = 0;
    336                
    337                 cmd = irc_parse_line( msg_buf );
    338                 ipc_command_exec( NULL, cmd, ipc_master_commands );
    339                 g_free( cmd );
    340         }
    341        
    342         g_free( msg_buf );
    343 }
    344 
    345 void ipc_to_children( char **cmd )
    346 {
    347         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    348         {
    349                 char *msg_buf = irc_build_line( cmd );
    350                 ipc_to_children_str( "%s", msg_buf );
    351                 g_free( msg_buf );
    352         }
    353         else if( global.conf->runmode == RUNMODE_DAEMON )
    354         {
    355                 GSList *l;
    356                
    357                 for( l = irc_connection_list; l; l = l->next )
    358                         ipc_command_exec( l->data, cmd, ipc_child_commands );
    359         }
    360 }
    361 
    362 void ipc_to_children_str( char *format, ... )
    363 {
    364         char *msg_buf;
    365         va_list params;
    366 
    367         va_start( params, format );
    368         msg_buf = g_strdup_vprintf( format, params );
    369         va_end( params );
    370        
    371         if( strlen( msg_buf ) > 512 )
    372         {
    373                 /* Don't send it, it's too long... */
    374         }
    375         else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    376         {
    377                 int msg_len = strlen( msg_buf );
    378                 GSList *l;
    379                
    380                 for( l = child_list; l; l = l->next )
    381                 {
    382                         struct bitlbee_child *c = l->data;
    383                         write( c->ipc_fd, msg_buf, msg_len );
    384398                }
    385399        }
     
    410424}
    411425
     426void ipc_master_free_fd( int fd )
     427{
     428        GSList *l;
     429        struct bitlbee_child *c;
     430       
     431        for( l = child_list; l; l = l->next )
     432        {
     433                c = l->data;
     434                if( c->ipc_fd == fd )
     435                {
     436                        ipc_master_free_one( c );
     437                        child_list = g_slist_remove( child_list, c );
     438                        break;
     439                }
     440        }
     441}
     442
    412443void ipc_master_free_all()
    413444{
     
    421452}
    422453
     454void ipc_child_disable()
     455{
     456        b_event_remove( global.listen_watch_source_id );
     457        close( global.listen_socket );
     458       
     459        global.listen_socket = -1;
     460}
     461
     462#ifndef _WIN32
    423463char *ipc_master_save_state()
    424464{
     
    461501}
    462502
    463 void ipc_master_set_statefile( char *fn )
    464 {
    465         statefile = g_strdup( fn );
    466 }
    467 
    468503
    469504static gboolean new_ipc_client( gpointer data, gint serversock, b_input_condition cond )
     
    486521}
    487522
    488 #ifndef _WIN32
    489523int ipc_master_listen_socket()
    490524{
     
    523557}
    524558#else
     559int ipc_master_listen_socket()
     560{
    525561        /* FIXME: Open named pipe \\.\BITLBEE */
     562        return 0;
     563}
    526564#endif
    527565
    528 int ipc_master_load_state()
     566int ipc_master_load_state( char *statefile )
    529567{
    530568        struct bitlbee_child *child;
     
    534572        if( statefile == NULL )
    535573                return 0;
     574       
    536575        fp = fopen( statefile, "r" );
    537576        unlink( statefile );    /* Why do it later? :-) */
  • ipc.h

    r9730d72 r6738a67  
    4444
    4545void ipc_master_free_one( struct bitlbee_child *child );
     46void ipc_master_free_fd( int fd );
    4647void ipc_master_free_all();
     48
     49void ipc_child_disable();
    4750
    4851void ipc_to_master( char **cmd );
     
    5558
    5659char *ipc_master_save_state();
    57 void ipc_master_set_statefile( char *fn );
    58 int ipc_master_load_state();
     60int ipc_master_load_state( char *statefile );
    5961int ipc_master_listen_socket();
    6062
  • irc.c

    r9730d72 r6738a67  
    2626#define BITLBEE_CORE
    2727#include "bitlbee.h"
     28#include "sock.h"
    2829#include "crypting.h"
    2930#include "ipc.h"
     
    4546}
    4647
     48static 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
    4777irc_t *irc_new( int fd )
    4878{
     
    6797        irc->mynick = g_strdup( ROOT_NICK );
    6898        irc->channel = g_strdup( ROOT_CHAN );
     99       
     100        irc->iconv = (GIConv) -1;
     101        irc->oconv = (GIConv) -1;
    69102       
    70103        if( global.conf->hostname )
     
    126159        set_add( &irc->set, "private", "true", set_eval_bool, irc );
    127160        set_add( &irc->set, "query_order", "lifo", NULL, irc );
     161        set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc );
    128162        set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
    129163        set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc );
     
    137171        irc->otr = otr_new();
    138172       
     173        /* Evaluator sets the iconv/oconv structures. */
     174        set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) );
     175       
    139176        return( irc );
    140177}
     
    174211        if( irc->sendbuffer && !immed )
    175212        {
    176                 /* We won't read from this socket anymore. Instead, we'll connect a timer
    177                    to it that should shut down the connection in a second, just in case
    178                    bitlbee_.._write doesn't do it first. */
     213                /* Set up a timeout event that should shut down the connection
     214                   in a second, just in case ..._write doesn't do it first. */
    179215               
    180216                b_event_remove( irc->r_watch_source_id );
    181                 irc->r_watch_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc );
     217                irc->r_watch_source_id = 0;
     218               
     219                b_event_remove( irc->ping_source_id );
     220                irc->ping_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc );
    182221        }
    183222        else
     
    195234
    196235/* Because we have no garbage collection, this is quite annoying */
    197 void irc_free(irc_t * irc)
    198 {
    199         account_t *account;
     236void irc_free( irc_t * irc )
     237{
    200238        user_t *user, *usertmp;
    201239       
     
    206244                        irc_usermsg( irc, "Error while saving settings!" );
    207245       
    208         closesocket( irc->fd );
    209        
    210         if( irc->ping_source_id > 0 )
    211                 b_event_remove( irc->ping_source_id );
    212         b_event_remove( irc->r_watch_source_id );
    213         if( irc->w_watch_source_id > 0 )
    214                 b_event_remove( irc->w_watch_source_id );
    215        
    216246        irc_connection_list = g_slist_remove( irc_connection_list, irc );
    217247       
    218         for (account = irc->accounts; account; account = account->next) {
    219                 if (account->ic) {
    220                         imc_logout(account->ic, TRUE);
    221                 } else if (account->reconnect) {
    222                         cancel_auto_reconnect(account);
    223                 }
    224         }
    225        
    226         g_free(irc->sendbuffer);
    227         g_free(irc->readbuffer);
    228        
    229         g_free(irc->nick);
    230         g_free(irc->user);
    231         g_free(irc->host);
    232         g_free(irc->realname);
    233         g_free(irc->password);
    234        
    235         g_free(irc->myhost);
    236         g_free(irc->mynick);
    237        
    238         g_free(irc->channel);
    239        
    240         while (irc->queries != NULL)
    241                 query_del(irc, irc->queries);
    242        
    243         while (irc->accounts)
    244                 if (irc->accounts->ic == NULL)
    245                         account_del(irc, irc->accounts);
     248        while( irc->accounts )
     249        {
     250                if( irc->accounts->ic )
     251                        imc_logout( irc->accounts->ic, FALSE );
     252                else if( irc->accounts->reconnect )
     253                        cancel_auto_reconnect( irc->accounts );
     254               
     255                if( irc->accounts->ic == NULL )
     256                        account_del( irc, irc->accounts );
    246257                else
    247258                        /* Nasty hack, but account_del() doesn't work in this
    248259                           case and we don't want infinite loops, do we? ;-) */
    249260                        irc->accounts = irc->accounts->next;
    250        
    251         while (irc->set)
    252                 set_del(&irc->set, irc->set->key);
    253        
    254         if (irc->users != NULL) {
     261        }
     262       
     263        while( irc->queries != NULL )
     264                query_del( irc, irc->queries );
     265       
     266        while( irc->set )
     267                set_del( &irc->set, irc->set->key );
     268       
     269        if (irc->users != NULL)
     270        {
    255271                user = irc->users;
    256                 while (user != NULL) {
    257                         g_free(user->nick);
    258                         g_free(user->away);
    259                         g_free(user->handle);
    260                         if(user->user!=user->nick) g_free(user->user);
    261                         if(user->host!=user->nick) g_free(user->host);
    262                         if(user->realname!=user->nick) g_free(user->realname);
    263                         b_event_remove(user->sendbuf_timer);
     272                while( user != NULL )
     273                {
     274                        g_free( user->nick );
     275                        g_free( user->away );
     276                        g_free( user->handle );
     277                        if( user->user != user->nick ) g_free( user->user );
     278                        if( user->host != user->nick ) g_free( user->host );
     279                        if( user->realname != user->nick ) g_free( user->realname );
     280                        b_event_remove( user->sendbuf_timer );
    264281                                       
    265282                        usertmp = user;
    266283                        user = user->next;
    267                         g_free(usertmp);
    268                 }
    269         }
    270        
    271         g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL);
    272         g_hash_table_destroy(irc->userhash);
    273        
    274         g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL);
    275         g_hash_table_destroy(irc->watches);
     284                        g_free( usertmp );
     285                }
     286        }
     287       
     288        if( irc->ping_source_id > 0 )
     289                b_event_remove( irc->ping_source_id );
     290        if( irc->r_watch_source_id > 0 )
     291                b_event_remove( irc->r_watch_source_id );
     292        if( irc->w_watch_source_id > 0 )
     293                b_event_remove( irc->w_watch_source_id );
     294       
     295        closesocket( irc->fd );
     296        irc->fd = -1;
     297       
     298        g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL );
     299        g_hash_table_destroy( irc->userhash );
     300       
     301        g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL );
     302        g_hash_table_destroy( irc->watches );
     303       
     304        if( irc->iconv != (GIConv) -1 )
     305                g_iconv_close( irc->iconv );
     306        if( irc->oconv != (GIConv) -1 )
     307                g_iconv_close( irc->oconv );
     308       
     309        g_free( irc->sendbuffer );
     310        g_free( irc->readbuffer );
     311       
     312        g_free( irc->nick );
     313        g_free( irc->user );
     314        g_free( irc->host );
     315        g_free( irc->realname );
     316        g_free( irc->password );
     317       
     318        g_free( irc->myhost );
     319        g_free( irc->mynick );
     320       
     321        g_free( irc->channel );
     322       
     323        g_free( irc->last_target );
    276324       
    277325        otr_free(irc->otr);
    278326       
    279         g_free(irc);
    280        
    281         if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON )
     327        g_free( irc );
     328       
     329        if( global.conf->runmode == RUNMODE_INETD ||
     330            global.conf->runmode == RUNMODE_FORKDAEMON ||
     331            ( global.conf->runmode == RUNMODE_DAEMON &&
     332              global.listen_socket == -1 &&
     333              irc_connection_list == NULL ) )
    282334                b_main_quit();
    283335}
     
    298350void irc_process( irc_t *irc )
    299351{
    300         char **lines, *temp, **cmd, *cs;
     352        char **lines, *temp, **cmd;
    301353        int i;
    302354
     
    307359                for( i = 0; *lines[i] != '\0'; i ++ )
    308360                {
    309                         char conv[IRC_MAX_LINE+1];
     361                        char *conv = NULL;
    310362                       
    311                         /* [WvG] Because irc_tokenize splits at every newline, the lines[] list
    312                             should end with an empty string. This is why this actually works.
    313                             Took me a while to figure out, Maurits. :-P */
     363                        /* [WvG] If the last line isn't empty, it's an incomplete line and we
     364                           should wait for the rest to come in before processing it. */
    314365                        if( lines[i+1] == NULL )
    315366                        {
     
    321372                        }
    322373                       
    323                         if( ( cs = set_getstr( &irc->set, "charset" ) ) )
    324                         {
    325                                 conv[IRC_MAX_LINE] = 0;
    326                                 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 )
     374                        if( irc->iconv != (GIConv) -1 )
     375                        {
     376                                gsize bytes_read, bytes_written;
     377                               
     378                                conv = g_convert_with_iconv( lines[i], -1, irc->iconv,
     379                                                             &bytes_read, &bytes_written, NULL );
     380                               
     381                                if( conv == NULL || bytes_read != strlen( lines[i] ) )
    327382                                {
    328383                                        /* GLib can do strange things if things are not in the expected charset,
     
    336391                                                                  "expect by changing the charset setting. See "
    337392                                                                  "`help set charset' for more information. Your "
    338                                                                   "message was ignored.", cs );
    339                                                 *conv = 0;
     393                                                                  "message was ignored.",
     394                                                                  set_getstr( &irc->set, "charset" ) );
     395                                               
     396                                                g_free( conv );
     397                                                conv = NULL;
    340398                                        }
    341399                                        else
    342400                                        {
    343401                                                irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost,
    344                                                            "Warning: invalid (non-UTF8) characters received at login time." );
     402                                                           "Warning: invalid characters received at login time." );
    345403                                               
    346                                                 strncpy( conv, lines[i], IRC_MAX_LINE );
     404                                                conv = g_strdup( lines[i] );
    347405                                                for( temp = conv; *temp; temp ++ )
    348406                                                        if( *temp & 0x80 )
     
    353411                        }
    354412                       
    355                         if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    356                                 continue;
    357                         irc_exec( irc, cmd );
     413                        if( lines[i] )
     414                        {
     415                                if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
     416                                        continue;
     417                                irc_exec( irc, cmd );
     418                                g_free( cmd );
     419                        }
    358420                       
    359                         g_free( cmd );
     421                        g_free( conv );
    360422                       
    361423                        /* Shouldn't really happen, but just in case... */
     
    381443char **irc_tokenize( char *buffer )
    382444{
    383         int i, j;
     445        int i, j, n = 3;
    384446        char **lines;
    385447
    386         /* Count the number of elements we're gonna need. */
    387         for( i = 0, j = 1; buffer[i] != '\0'; i ++ )
    388         {
    389                 if( buffer[i] == '\n' )
    390                         if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
    391                                 j ++;
    392         }
    393        
    394         /* Allocate j+1 elements. */
    395         lines = g_new( char *, j + 1 );
     448        /* Allocate n+1 elements. */
     449        lines = g_new( char *, n + 1 );
     450       
     451        lines[0] = buffer;
     452       
     453        /* Split the buffer in several strings, and accept any kind of line endings,
     454         * knowing that ERC on Windows may send something interesting like \r\r\n,
     455         * and surely there must be clients that think just \n is enough... */
     456        for( i = 0, j = 0; buffer[i] != '\0'; i ++ )
     457        {
     458                if( buffer[i] == '\r' || buffer[i] == '\n' )
     459                {
     460                        while( buffer[i] == '\r' || buffer[i] == '\n' )
     461                                buffer[i++] = '\0';
     462                       
     463                        lines[++j] = buffer + i;
     464                       
     465                        if( j >= n )
     466                        {
     467                                n *= 2;
     468                                lines = g_renew( char *, lines, n + 1 );
     469                        }
     470
     471                        if( buffer[i] == '\0' )
     472                                break;
     473                }
     474        }
    396475       
    397476        /* NULL terminate our list. */
    398         lines[j] = NULL;
    399        
    400         lines[0] = buffer;
    401        
    402         /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
    403          * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
    404          */
    405         for( i = 0, j = 0; buffer[i] != '\0'; i ++)
    406         {
    407                 if( buffer[i] == '\n' )
    408                 {
    409                         buffer[i] = '\0';
    410                        
    411                         if( i > 0 && buffer[i-1] == '\r' )
    412                                 buffer[i-1] = '\0';
    413                         if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
    414                                 lines[++j] = buffer + i + 1;
    415                 }
    416         }
    417        
    418         return( lines );
     477        lines[++j] = NULL;
     478       
     479        return lines;
    419480}
    420481
     
    550611
    551612        return;
    552 
    553613}
    554614
     
    556616{
    557617        int size;
    558         char line[IRC_MAX_LINE+1], *cs;
     618        char line[IRC_MAX_LINE+1];
    559619               
    560620        /* Don't try to write anything new anymore when shutting down. */
     
    562622                return;
    563623       
    564         line[IRC_MAX_LINE] = 0;
     624        memset( line, 0, sizeof( line ) );
    565625        g_vsnprintf( line, IRC_MAX_LINE - 2, format, params );
    566        
    567626        strip_newlines( line );
    568         if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
    569         {
    570                 char conv[IRC_MAX_LINE+1];
    571                
    572                 conv[IRC_MAX_LINE] = 0;
    573                 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 )
    574                         strcpy( line, conv );
    575         }
    576         strcat( line, "\r\n" );
     627       
     628        if( irc->oconv != (GIConv) -1 )
     629        {
     630                gsize bytes_read, bytes_written;
     631                char *conv;
     632               
     633                conv = g_convert_with_iconv( line, -1, irc->oconv,
     634                                             &bytes_read, &bytes_written, NULL );
     635
     636                if( bytes_read == strlen( line ) )
     637                        strncpy( line, conv, IRC_MAX_LINE - 2 );
     638               
     639                g_free( conv );
     640        }
     641        g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 );
    577642       
    578643        if( irc->sendbuffer != NULL )
     
    753818        irc->umode[0] = '\0';
    754819        irc_umode_set( irc, "+" UMODE, 1 );
    755 
    756         u = user_add( irc, irc->mynick );
     820u = user_add( irc, irc->mynick );
    757821        u->host = g_strdup( irc->myhost );
    758822        u->realname = g_strdup( ROOT_FN );
     
    782846       
    783847        irc->status |= USTATUS_LOGGED_IN;
     848       
     849        /* This is for bug #209 (use PASS to identify to NickServ). */
     850        if( irc->password != NULL )
     851        {
     852                char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL };
     853               
     854                irc_setpass( irc, NULL );
     855                root_command( irc, send_cmd );
     856                g_free( send_cmd[1] );
     857        }
    784858}
    785859
     
    791865        if( !f )
    792866        {
    793                 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.\n\nOTR users please note: Private key files are owned by the user BitlBee is running as." );
     867                irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n"
     868                                  "If you've never used BitlBee before, please do read the help "
     869                                  "information using the \x02help\x02 command. Lots of FAQs are "
     870                                  "answered there.\n"
     871                                  "OTR users please note: Private key files are owned by the user "
     872                                  "BitlBee is running as.\n"
     873                                  "If you already have an account on this server, just use the "
     874                                  "\x02identify\x02 command to identify yourself." );
    794875        }
    795876        else
  • irc.h

    r9730d72 r6738a67  
    6363        char *sendbuffer;
    6464        char *readbuffer;
     65        GIConv iconv, oconv;
    6566
    6667        int sentbytes;
     
    7172        char *host;
    7273        char *realname;
    73         char *password;
     74        char *password; /* HACK: Used to save the user's password, but before
     75                           logging in, this may contain a password we should
     76                           send to identify after USER/NICK are received. */
    7477
    7578        char umode[8];
  • irc_commands.c

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

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

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

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

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

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

    r9730d72 r6738a67  
    3333#define BITLBEE_CORE
    3434#include "nogaim.h"
     35#include "base64.h"
    3536#include <stdio.h>
    3637#include <stdlib.h>
     
    5960        strcpy(text, text2);
    6061        g_free(text2);
    61 }
    62 
    63 char *normalize(const char *s)
    64 {
    65         static char buf[BUF_LEN];
    66         char *t, *u;
    67         int x = 0;
    68 
    69         g_return_val_if_fail((s != NULL), NULL);
    70 
    71         u = t = g_strdup(s);
    72 
    73         strcpy(t, s);
    74         g_strdown(t);
    75 
    76         while (*t && (x < BUF_LEN - 1)) {
    77                 if (*t != ' ') {
    78                         buf[x] = *t;
    79                         x++;
    80                 }
    81                 t++;
    82         }
    83         buf[x] = '\0';
    84         g_free(u);
    85         return buf;
    8662}
    8763
     
    408384void random_bytes( unsigned char *buf, int count )
    409385{
     386#ifndef _WIN32
    410387        static int use_dev = -1;
    411388       
     
    457434       
    458435        if( !use_dev )
     436#endif
    459437        {
    460438                int i;
     
    608586                return sockerr_again();
    609587}
     588
     589/* Returns values: -1 == Failure (base64-decoded to something unexpected)
     590                    0 == Okay
     591                    1 == Password doesn't match the hash. */
     592int md5_verify_password( char *password, char *hash )
     593{
     594        md5_byte_t *pass_dec = NULL;
     595        md5_byte_t pass_md5[16];
     596        md5_state_t md5_state;
     597        int ret = -1, i;
     598       
     599        if( base64_decode( hash, &pass_dec ) == 21 )
     600        {
     601                md5_init( &md5_state );
     602                md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) );
     603                md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */
     604                md5_finish( &md5_state, pass_md5 );
     605               
     606                for( i = 0; i < 16; i ++ )
     607                {
     608                        if( pass_dec[i] != pass_md5[i] )
     609                        {
     610                                ret = 1;
     611                                break;
     612                        }
     613                }
     614               
     615                /* If we reached the end of the loop, it was a match! */
     616                if( i == 16 )
     617                        ret = 0;
     618        }
     619       
     620        g_free( pass_dec );
     621
     622        return ret;
     623}
  • lib/misc.h

    r9730d72 r6738a67  
    4141G_MODULE_EXPORT char *add_cr( char *text );
    4242G_MODULE_EXPORT char *strip_newlines(char *source);
    43 G_MODULE_EXPORT char *normalize( const char *s );
    4443
    4544G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
     
    6766G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl );
    6867
     68G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
     69
    6970#endif
  • lib/proxy.c

    r9730d72 r6738a67  
    114114{
    115115        struct sockaddr_in *sin;
     116        struct sockaddr_in me;
    116117        int fd = -1;
    117118
     
    127128
    128129        sock_make_nonblocking(fd);
     130       
     131        if( global.conf->iface_out )
     132        {
     133                me.sin_family = AF_INET;
     134                me.sin_port = 0;
     135                me.sin_addr.s_addr = inet_addr( global.conf->iface_out );
     136               
     137                if( bind( fd, (struct sockaddr *) &me, sizeof( me ) ) != 0 )
     138                        event_debug( "bind( %d, \"%s\" ) failure\n", fd, global.conf->iface_out );
     139        }
    129140       
    130141        event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd);
     
    530541        struct PHB *phb;
    531542       
    532         if (!host || !port || (port == -1) || !func || strlen(host) > 128) {
     543        if (!host || port <= 0 || !func || strlen(host) > 128) {
    533544                return -1;
    534545        }
     
    538549        phb->data = data;
    539550       
    540         if ((proxytype == PROXY_NONE) || strlen(proxyhost) > 0 || !proxyport || (proxyport == -1))
     551        if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0)
    541552                return proxy_connect_none(host, port, phb);
    542553        else if (proxytype == PROXY_HTTP)
  • lib/ssl_bogus.c

    r9730d72 r6738a67  
    6565        return GAIM_INPUT_READ;
    6666}
     67
     68int ssl_pending( void *conn )
     69{
     70        return 0;
     71}
  • lib/ssl_client.h

    r9730d72 r6738a67  
    6363G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
    6464
     65/* See ssl_openssl.c for an explanation. */
     66G_MODULE_EXPORT int ssl_pending( void *conn );
     67
    6568/* Abort the SSL connection and disconnect the socket. Do not use close()
    6669   directly, both the SSL library and the peer will be unhappy! */
  • lib/ssl_gnutls.c

    r9730d72 r6738a67  
    216216}
    217217
     218/* See ssl_openssl.c for an explanation. */
     219int ssl_pending( void *conn )
     220{
     221        return 0;
     222}
     223
    218224void ssl_disconnect( void *conn_ )
    219225{
  • lib/ssl_nss.c

    r9730d72 r6738a67  
    175175}
    176176
     177/* See ssl_openssl.c for an explanation. */
     178int ssl_pending( void *conn )
     179{
     180        return 0;
     181}
     182
    177183void ssl_disconnect( void *conn_ )
    178184{
  • lib/ssl_openssl.c

    r9730d72 r6738a67  
    6868       
    6969        conn->fd = proxy_connect( host, port, ssl_connected, conn );
     70        if( conn->fd < 0 )
     71        {
     72                g_free( conn );
     73                return NULL;
     74        }
     75       
    7076        conn->func = func;
    7177        conn->data = data;
    7278        conn->inpa = -1;
    73        
    74         if( conn->fd < 0 )
    75         {
    76                 g_free( conn );
    77                 return NULL;
    78         }
    7979       
    8080        return conn;
     
    236236}
    237237
     238/* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info:
     239   http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
     240   http://www.openssl.org/docs/ssl/SSL_pending.html
     241   
     242   Required because OpenSSL empties the TCP buffer completely but doesn't
     243   necessarily give us all the unencrypted data.
     244   
     245   Returns 0 if there's nothing left or if we don't have to care (GnuTLS),
     246   1 if there's more data. */
     247int ssl_pending( void *conn )
     248{
     249        return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ?
     250               SSL_pending( ((struct scd*)conn)->ssl ) > 0 : 0;
     251}
     252
    238253void ssl_disconnect( void *conn_ )
    239254{
  • lib/url.c

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

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

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

    r9730d72 r6738a67  
    7171        struct xt_node *cur;
    7272       
    73         struct xt_handler_entry *handlers;
     73        const struct xt_handler_entry *handlers;
    7474        gpointer data;
    7575       
     
    7777};
    7878
    79 struct xt_parser *xt_new( gpointer data );
     79struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data );
    8080void xt_reset( struct xt_parser *xt );
    8181int xt_feed( struct xt_parser *xt, char *text, int text_len );
  • nick.c

    r9730d72 r6738a67  
    4747       
    4848        store_handle = clean_handle( handle );
     49        store_nick[MAX_NICK_LENGTH] = 0;
    4950        strncpy( store_nick, nick, MAX_NICK_LENGTH );
    5051        nick_strip( store_nick );
  • otr.c

    r9730d72 r6738a67  
    4646#include <unistd.h>
    4747#include <assert.h>
     48#include <signal.h>
    4849
    4950
     
    102103};
    103104
     105typedef struct {
     106        void *fst;
     107        void *snd;
     108} pair_t;       
     109
    104110
    105111/** misc. helpers/subroutines: **/
     
    124130
    125131/* some yes/no handlers */
    126 void yes_keygen(gpointer w, void *data);
    127 void yes_forget_fingerprint(gpointer w, void *data);
    128 void yes_forget_context(gpointer w, void *data);
    129 void yes_forget_key(gpointer w, void *data);
     132void yes_keygen(void *data);
     133void yes_forget_fingerprint(void *data);
     134void yes_forget_context(void *data);
     135void yes_forget_key(void *data);
    130136
    131137/* helper to make sure accountname and protocol match the incoming "opdata" */
     
    841847}
    842848
    843 void yes_forget_fingerprint(gpointer w, void *data)
    844 {
    845         irc_t *irc = (irc_t *)w;
    846         Fingerprint *fp = (Fingerprint *)data;
     849void yes_forget_fingerprint(void *data)
     850{
     851        pair_t *p = (pair_t *)data;
     852        irc_t *irc = (irc_t *)p->fst;
     853        Fingerprint *fp = (Fingerprint *)p->snd;
     854
     855        g_free(p);
    847856       
    848857        if(fp == fp->context->active_fingerprint) {
     
    854863}
    855864
    856 void yes_forget_context(gpointer w, void *data)
    857 {
    858         irc_t *irc = (irc_t *)w;
    859         ConnContext *ctx = (ConnContext *)data;
     865void yes_forget_context(void *data)
     866{
     867        pair_t *p = (pair_t *)data;
     868        irc_t *irc = (irc_t *)p->fst;
     869        ConnContext *ctx = (ConnContext *)p->snd;
     870
     871        g_free(p);
    860872       
    861873        if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
     
    870882}
    871883
    872 void yes_forget_key(gpointer w, void *data)
     884void yes_forget_key(void *data)
    873885{
    874886        OtrlPrivKey *key = (OtrlPrivKey *)data;
     
    889901                char human[54];
    890902                char *s;
     903                pair_t *p;
    891904               
    892905                if(!args[3]) {
     
    922935                otrl_privkey_hash_to_human(human, fp->fingerprint);
    923936                s = g_strdup_printf("about to forget fingerprint %s, are you sure?", human);
    924                 query_add(irc, NULL, s, yes_forget_fingerprint, NULL, fp);
     937                p = g_malloc(sizeof(pair_t));
     938                if(!p)
     939                        return;
     940                p->fst = irc;
     941                p->snd = fp;
     942                query_add(irc, NULL, s, yes_forget_fingerprint, NULL, p);
    925943                g_free(s);
    926944        }
     
    931949                ConnContext *ctx;
    932950                char *s;
     951                pair_t *p;
    933952               
    934953                /* TODO: allow context specs ("user/proto/account") in 'otr forget contex'? */
     
    952971               
    953972                s = g_strdup_printf("about to forget otr data about %s, are you sure?", args[2]);
    954                 query_add(irc, NULL, s, yes_forget_context, NULL, ctx);
     973                p = g_malloc(sizeof(pair_t));
     974                if(!p)
     975                        return;
     976                p->fst = irc;
     977                p->snd = ctx;
     978                query_add(irc, NULL, s, yes_forget_context, NULL, p);
    955979                g_free(s);
    956980        }
     
    16601684}
    16611685
    1662 void yes_keygen(gpointer w, void *data)
     1686void yes_keygen(void *data)
    16631687{
    16641688        account_t *acc = (account_t *)data;
  • protocols/jabber/Makefile

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

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

    r9730d72 r6738a67  
    3333#include "jabber.h"
    3434#include "md5.h"
    35 #include "base64.h"
    3635
    3736GSList *jabber_connections;
    3837
     38/* First enty is the default */
     39static const int jabber_port_list[] = {
     40        5222,
     41        5223,
     42        5220,
     43        5221,
     44        5224,
     45        5225,
     46        5226,
     47        5227,
     48        5228,
     49        5229,
     50        80,
     51        443,
     52        0
     53};
     54
    3955static void jabber_init( account_t *acc )
    4056{
    4157        set_t *s;
    42        
    43         s = set_add( &acc->set, "port", JABBER_PORT_DEFAULT, set_eval_int, acc );
     58        char str[16];
     59       
     60        g_snprintf( str, sizeof( str ), "%d", jabber_port_list[0] );
     61        s = set_add( &acc->set, "port", str, set_eval_int, acc );
    4462        s->flags |= ACC_SET_OFFLINE_ONLY;
    4563       
     
    7290        struct ns_srv_reply *srv = NULL;
    7391        char *connect_to, *s;
     92        int i;
    7493       
    7594        /* For now this is needed in the _connected() handlers if using
     
    177196        imcb_log( ic, "Connecting" );
    178197       
    179         if( set_getint( &acc->set, "port" ) < JABBER_PORT_MIN ||
    180             set_getint( &acc->set, "port" ) > JABBER_PORT_MAX )
    181         {
    182                 imcb_log( ic, "Incorrect port number, must be in the %d-%d range",
    183                                JABBER_PORT_MIN, JABBER_PORT_MAX );
     198        for( i = 0; jabber_port_list[i] > 0; i ++ )
     199                if( set_getint( &acc->set, "port" ) == jabber_port_list[i] )
     200                        break;
     201
     202        if( jabber_port_list[i] == 0 )
     203        {
     204                imcb_log( ic, "Illegal port number" );
    184205                imc_logout( ic, FALSE );
    185206                return;
     
    219240}
    220241
     242/* This generates an unfinished md5_state_t variable. Every time we generate
     243   an ID, we finish the state by adding a sequence number and take the hash. */
    221244static void jabber_generate_id_hash( struct jabber_data *jd )
    222245{
    223         md5_state_t id_hash;
    224         md5_byte_t binbuf[16];
     246        md5_byte_t binbuf[4];
    225247        char *s;
    226248       
    227         md5_init( &id_hash );
    228         md5_append( &id_hash, (unsigned char *) jd->username, strlen( jd->username ) );
    229         md5_append( &id_hash, (unsigned char *) jd->server, strlen( jd->server ) );
     249        md5_init( &jd->cached_id_prefix );
     250        md5_append( &jd->cached_id_prefix, (unsigned char *) jd->username, strlen( jd->username ) );
     251        md5_append( &jd->cached_id_prefix, (unsigned char *) jd->server, strlen( jd->server ) );
    230252        s = set_getstr( &jd->ic->acc->set, "resource" );
    231         md5_append( &id_hash, (unsigned char *) s, strlen( s ) );
    232         random_bytes( binbuf, 16 );
    233         md5_append( &id_hash, binbuf, 16 );
    234         md5_finish( &id_hash, binbuf );
    235        
    236         s = base64_encode( binbuf, 9 );
    237         jd->cached_id_prefix = g_strdup_printf( "%s%s", JABBER_CACHED_ID, s );
    238         g_free( s );
     253        md5_append( &jd->cached_id_prefix, (unsigned char *) s, strlen( s ) );
     254        random_bytes( binbuf, 4 );
     255        md5_append( &jd->cached_id_prefix, binbuf, 4 );
    239256}
    240257
  • protocols/jabber/jabber.h

    r9730d72 r6738a67  
    8686        char *away_message;
    8787       
    88         char *cached_id_prefix;
     88        md5_state_t cached_id_prefix;
    8989        GHashTable *node_cache;
    9090        GHashTable *buddies;
     
    134134
    135135#define JABBER_XMLCONSOLE_HANDLE "xmlconsole"
    136 
    137 #define JABBER_PORT_DEFAULT "5222"
    138 #define JABBER_PORT_MIN 5220
    139 #define JABBER_PORT_MAX 5229
    140136
    141137/* Prefixes to use for packet IDs (mainly for IQ packets ATM). Usually the
  • protocols/jabber/jabber_util.c

    r9730d72 r6738a67  
    2323
    2424#include "jabber.h"
     25#include "md5.h"
     26#include "base64.h"
    2527
    2628static unsigned int next_id = 1;
     
    134136        struct jabber_data *jd = ic->proto_data;
    135137        struct jabber_cache_entry *entry = g_new0( struct jabber_cache_entry, 1 );
    136         char *id;
    137        
    138         id = g_strdup_printf( "%s%05x", jd->cached_id_prefix, ( next_id++ ) & 0xfffff );
     138        md5_state_t id_hash;
     139        md5_byte_t id_sum[16];
     140        char *id, *asc_hash;
     141       
     142        next_id ++;
     143       
     144        id_hash = jd->cached_id_prefix;
     145        md5_append( &id_hash, (md5_byte_t*) &next_id, sizeof( next_id ) );
     146        md5_finish( &id_hash, id_sum );
     147        asc_hash = base64_encode( id_sum, 12 );
     148       
     149        id = g_strdup_printf( "%s%s", JABBER_CACHED_ID, asc_hash );
    139150        xt_add_attr( node, "id", id );
    140151        g_free( id );
     152        g_free( asc_hash );
    141153       
    142154        entry->node = node;
     
    184196       
    185197        if( ( s = xt_find_attr( node, "id" ) ) == NULL ||
    186             strncmp( s, jd->cached_id_prefix, strlen( jd->cached_id_prefix ) ) != 0 )
     198            strncmp( s, JABBER_CACHED_ID, strlen( JABBER_CACHED_ID ) ) != 0 )
    187199        {
    188200                /* Silently ignore it, without an ID (or a non-cache
     
    196208        if( entry == NULL )
    197209        {
     210                /*
     211                There's no longer an easy way to see if we generated this
     212                one or someone else, and there's a ten-minute timeout anyway,
     213                so meh.
     214               
    198215                imcb_log( ic, "Warning: Received %s-%s packet with unknown/expired ID %s!",
    199216                              node->name, xt_find_attr( node, "type" ) ? : "(no type)", s );
     217                */
    200218        }
    201219        else if( entry->func )
     
    246264};
    247265
    248 static void jabber_buddy_ask_yes( gpointer w, struct jabber_buddy_ask_data *bla )
    249 {
     266static void jabber_buddy_ask_yes( void *data )
     267{
     268        struct jabber_buddy_ask_data *bla = data;
     269       
    250270        presence_send_request( bla->ic, bla->handle, "subscribed" );
    251271       
     
    257277}
    258278
    259 static void jabber_buddy_ask_no( gpointer w, struct jabber_buddy_ask_data *bla )
    260 {
     279static void jabber_buddy_ask_no( void *data )
     280{
     281        struct jabber_buddy_ask_data *bla = data;
     282       
    261283        presence_send_request( bla->ic, bla->handle, "subscribed" );
    262284       
     
    286308        len = strlen( orig );
    287309        new = g_new( char, len + 1 );
    288         for( i = 0; i < len; i ++ )
     310       
     311        /* So it turns out the /resource part is case sensitive. Yeah, and
     312           it's Unicode but feck Unicode. :-P So stop once we see a slash. */
     313        for( i = 0; i < len && orig[i] != '/' ; i ++ )
    289314                new[i] = tolower( orig[i] );
     315        for( ; orig[i]; i ++ )
     316                new[i] = orig[i];
    290317       
    291318        new[i] = 0;
     
    330357                {
    331358                        /* Check for dupes. */
    332                         if( g_strcasecmp( bi->resource, s + 1 ) == 0 )
     359                        if( strcmp( bi->resource, s + 1 ) == 0 )
    333360                        {
    334361                                *s = '/';
     
    383410        if( ( s = strchr( jid, '/' ) ) )
    384411        {
    385                 int none_found = 0;
     412                int bare_exists = 0;
    386413               
    387414                *s = 0;
     
    406433                        /* See if there's an exact match. */
    407434                        for( ; bud; bud = bud->next )
    408                                 if( g_strcasecmp( bud->resource, s + 1 ) == 0 )
     435                                if( strcmp( bud->resource, s + 1 ) == 0 )
    409436                                        break;
    410437                }
    411438                else
    412439                {
    413                         /* This hack is there to make sure that O_CREAT will
    414                            work if there's already another resouce present
    415                            for this JID, even if it's an unknown buddy. This
    416                            is done to handle conferences properly. */
    417                         none_found = 1;
    418                         /* TODO(wilmer): Find out what I was thinking when I
    419                            wrote this??? And then fix it. This makes me sad... */
    420                 }
    421                
    422                 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && ( imcb_find_buddy( ic, jid ) || !none_found ) )
     440                        /* This variable tells the if down here that the bare
     441                           JID already exists and we should feel free to add
     442                           more resources, if the caller asked for that. */
     443                        bare_exists = 1;
     444                }
     445               
     446                if( bud == NULL && ( flags & GET_BUDDY_CREAT ) &&
     447                    ( !bare_exists || imcb_find_buddy( ic, jid ) ) )
    423448                {
    424449                        *s = '/';
     
    445470                        /* We want an exact match, so in thise case there shouldn't be a /resource. */
    446471                        return NULL;
    447                 else if( ( bud->resource == NULL || bud->next == NULL ) )
     472                else if( bud->resource == NULL || bud->next == NULL )
    448473                        /* No need for selection if there's only one option. */
    449474                        return bud;
     
    521546                   matches), removing it is simple. (And the hash reference
    522547                   should be removed too!) */
    523                 if( bud->next == NULL && ( ( s == NULL || bud->resource == NULL ) || g_strcasecmp( bud->resource, s + 1 ) == 0 ) )
     548                if( bud->next == NULL &&
     549                    ( ( s == NULL && bud->resource == NULL ) ||
     550                      ( bud->resource && s && strcmp( bud->resource, s + 1 ) == 0 ) ) )
    524551                {
    525552                        g_hash_table_remove( jd->buddies, bud->bare_jid );
     
    544571                {
    545572                        for( bi = bud, prev = NULL; bi; bi = (prev=bi)->next )
    546                                 if( g_strcasecmp( bi->resource, s + 1 ) == 0 )
     573                                if( strcmp( bi->resource, s + 1 ) == 0 )
    547574                                        break;
    548575                       
  • protocols/jabber/message.c

    r9730d72 r6738a67  
    4949        {
    5050                GString *fullmsg = g_string_new( "" );
     51
     52                for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
     53                {
     54                        char *ns = xt_find_attr( c, "xmlns" ), *room;
     55                        struct xt_node *inv, *reason;
     56                       
     57                        if( strcmp( ns, XMLNS_MUC_USER ) == 0 &&
     58                            ( inv = xt_find_node( c->children, "invite" ) ) )
     59                        {
     60                                room = from;
     61                                from = xt_find_attr( inv, "from" ) ? : from;
     62
     63                                g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Invitation to chatroom %s >>\n", room );
     64                                if( ( reason = xt_find_node( inv->children, "reason" ) ) && reason->text_len > 0 )
     65                                        g_string_append( fullmsg, reason->text );
     66                        }
     67                }
    5168               
    5269                if( ( s = strchr( from, '/' ) ) )
  • protocols/msn/msn.h

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

    r9730d72 r6738a67  
    9090};
    9191
    92 static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla )
    93 {
     92static void msn_buddy_ask_yes( void *data )
     93{
     94        struct msn_buddy_ask_data *bla = data;
     95       
    9496        msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname );
    9597       
     
    102104}
    103105
    104 static void msn_buddy_ask_no( gpointer w, struct msn_buddy_ask_data *bla )
    105 {
     106static void msn_buddy_ask_no( void *data )
     107{
     108        struct msn_buddy_ask_data *bla = data;
     109       
    106110        msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname );
    107111       
  • protocols/msn/ns.c

    r9730d72 r6738a67  
    3434static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
    3535
    36 static void msn_auth_got_passport_id( struct passport_reply *rep );
     36static void msn_auth_got_passport_token( struct msn_auth_data *mad );
    3737
    3838gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
     
    178178                       
    179179                        debug( "Connecting to a new switchboard with key %s", cmd[5] );
    180                         sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW );
     180
     181                        if( ( sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW ) ) == NULL )
     182                        {
     183                                /* Although this isn't strictly fatal for the NS connection, it's
     184                                   definitely something serious (we ran out of file descriptors?). */
     185                                imcb_error( ic, "Could not create new switchboard" );
     186                                imc_logout( ic, TRUE );
     187                                return( 0 );
     188                        }
    181189                       
    182190                        if( md->msgq )
     
    214222                {
    215223                        /* Time for some Passport black magic... */
    216                         if( !passport_get_id( msn_auth_got_passport_id, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
     224                        if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
    217225                        {
    218226                                imcb_error( ic, "Error while contacting Passport server" );
     
    270278                if( num_parts == 5 )
    271279                {
     280                        int i, groupcount;
     281                       
     282                        groupcount = atoi( cmd[4] );
     283                        if( groupcount > 0 )
     284                        {
     285                                /* valgrind says this is leaking memory, I'm guessing
     286                                   that this happens during server redirects. */
     287                                if( md->grouplist )
     288                                {
     289                                        for( i = 0; i < md->groupcount; i ++ )
     290                                                g_free( md->grouplist[i] );
     291                                        g_free( md->grouplist );
     292                                }
     293                               
     294                                md->groupcount = groupcount;
     295                                md->grouplist = g_new0( char *, md->groupcount );
     296                        }
     297                       
    272298                        md->buddycount = atoi( cmd[3] );
    273                         md->groupcount = atoi( cmd[4] );
    274                         if( md->groupcount > 0 )
    275                                 md->grouplist = g_new0( char *, md->groupcount );
    276                        
    277299                        if( !*cmd[3] || md->buddycount == 0 )
    278300                                msn_logged_in( ic );
     
    468490                debug( "Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4] );
    469491               
    470                 sb = msn_sb_create( ic, server, port, cmd[4], session );
    471                 sb->who = g_strdup( cmd[5] );
     492                if( ( sb = msn_sb_create( ic, server, port, cmd[4], session ) ) == NULL )
     493                {
     494                        /* Although this isn't strictly fatal for the NS connection, it's
     495                           definitely something serious (we ran out of file descriptors?). */
     496                        imcb_error( ic, "Could not create new switchboard" );
     497                        imc_logout( ic, TRUE );
     498                        return( 0 );
     499                }
     500                else
     501                {
     502                        sb->who = g_strdup( cmd[5] );
     503                }
    472504        }
    473505        else if( strcmp( cmd[0], "ADD" ) == 0 )
     
    647679                                        imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders );
    648680                                }
     681                               
     682                                g_free( inbox );
     683                                g_free( folders );
    649684                        }
    650685                        else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 )
     
    674709}
    675710
    676 static void msn_auth_got_passport_id( struct passport_reply *rep )
     711static void msn_auth_got_passport_token( struct msn_auth_data *mad )
    677712{
    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" );
     713        struct im_connection *ic = mad->data;
     714        struct msn_data *md;
     715       
     716        /* Dead connection? */
     717        if( g_slist_find( msn_connections, ic ) == NULL )
     718                return;
     719       
     720        md = ic->proto_data;
     721        if( mad->token )
     722        {
     723                char buf[1024];
     724               
     725                g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token );
     726                msn_write( ic, buf, strlen( buf ) );
     727        }
     728        else
     729        {
     730                imcb_error( ic, "Error during Passport authentication: %s", mad->error );
    687731                imc_logout( ic, TRUE );
    688732        }
    689         else
    690         {
    691                 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );
    692                 msn_write( ic, buf, strlen( buf ) );
    693         }
    694733}
  • protocols/msn/passport.c

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

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

    r9730d72 r6738a67  
    343343/* dialogs.c */
    344344
    345 void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont )
     345void imcb_ask( struct im_connection *ic, char *msg, void *data,
     346               query_callback doit, query_callback dont )
    346347{
    347348        query_add( ic->irc, ic, msg, doit, dont, data );
     
    495496};
    496497
    497 void show_got_added_no( gpointer w, struct show_got_added_data *data )
    498 {
    499         g_free( data->handle );
     498void show_got_added_no( void *data )
     499{
     500        g_free( ((struct show_got_added_data*)data)->handle );
    500501        g_free( data );
    501502}
    502503
    503 void 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 );
     504void 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 );
    509512}
    510513
  • protocols/nogaim.h

    r9730d72 r6738a67  
    4242#include "account.h"
    4343#include "proxy.h"
     44#include "query.h"
    4445#include "md5.h"
    45 
    46 #define BUF_LEN MSG_LEN
    47 #define BUF_LONG ( BUF_LEN * 2 )
    48 #define MSG_LEN 2048
    49 #define BUF_LEN MSG_LEN
    5046
    5147#define BUDDY_ALIAS_MAXLEN 388   /* because MSN names can be 387 characters */
     
    265261 * - 'doit' or 'dont' will be called depending of the answer of the user.
    266262 */
    267 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont );
     263G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont );
    268264G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname );
    269265
  • protocols/oscar/oscar.c

    r9730d72 r6738a67  
    6060
    6161#define OSCAR_GROUP "Friends"
     62
     63#define BUF_LEN 2048
     64#define BUF_LONG ( BUF_LEN * 2 )
    6265
    6366/* Don't know if support for UTF8 is really working. For now it's UTF16 here.
     
    240243};
    241244static int msgerrreasonlen = 25;
     245
     246/* Hurray, this function is NOT thread-safe \o/ */
     247static char *normalize(const char *s)
     248{
     249        static char buf[BUF_LEN];
     250        char *t, *u;
     251        int x = 0;
     252
     253        g_return_val_if_fail((s != NULL), NULL);
     254
     255        u = t = g_strdup(s);
     256
     257        strcpy(t, s);
     258        g_strdown(t);
     259
     260        while (*t && (x < BUF_LEN - 1)) {
     261                if (*t != ' ' && *t != '!') {
     262                        buf[x] = *t;
     263                        x++;
     264                }
     265                t++;
     266        }
     267        buf[x] = '\0';
     268        g_free(u);
     269        return buf;
     270}
    242271
    243272static gboolean oscar_callback(gpointer data, gint source,
     
    10021031        }
    10031032
    1004         tmp = g_strdup(normalize(ic->acc->user));
    1005         if (!strcmp(tmp, normalize(info->sn)))
     1033        if (!aim_sncmp(ic->acc->user, info->sn))
    10061034                g_snprintf(ic->displayname, sizeof(ic->displayname), "%s", info->sn);
    1007         g_free(tmp);
    1008 
    1009         imcb_buddy_status(ic, info->sn, flags, state_string, NULL);
    1010         /* imcb_buddy_times(ic, info->sn, signon, time_idle); */
     1035
     1036        tmp = normalize(info->sn);
     1037        imcb_buddy_status(ic, tmp, flags, state_string, NULL);
     1038        /* imcb_buddy_times(ic, tmp, signon, time_idle); */
     1039
    10111040
    10121041        return 1;
     
    10221051        va_end(ap);
    10231052
    1024         imcb_buddy_status(ic, info->sn, 0, NULL, NULL );
     1053        imcb_buddy_status(ic, normalize(info->sn), 0, NULL, NULL );
    10251054
    10261055        return 1;
     
    10781107       
    10791108        strip_linefeed(tmp);
    1080         imcb_buddy_msg(ic, userinfo->sn, tmp, flags, 0);
     1109        imcb_buddy_msg(ic, normalize(userinfo->sn), tmp, flags, 0);
    10811110        g_free(tmp);
    10821111       
     
    10841113}
    10851114
    1086 void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv);
    1087 void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv);
     1115void oscar_accept_chat(void *data);
     1116void oscar_reject_chat(void *data);
    10881117       
    10891118static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
     
    11191148}
    11201149
    1121 static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) {
     1150static void gaim_icq_authgrant(void *data_) {
     1151        struct icq_auth *data = data_;
    11221152        char *uin, message;
    11231153        struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
     
    11341164}
    11351165
    1136 static void gaim_icq_authdeny(gpointer w, struct icq_auth *data) {
     1166static void gaim_icq_authdeny(void *data_) {
     1167        struct icq_auth *data = data_;
    11371168        char *uin, *message;
    11381169        struct oscar_data *od = (struct oscar_data *)data->ic->proto_data;
     
    11751206                        message = g_strdup(args->msg);
    11761207                        strip_linefeed(message);
    1177                         imcb_buddy_msg(ic, uin, message, 0, 0);
     1208                        imcb_buddy_msg(ic, normalize(uin), message, 0, 0);
    11781209                        g_free(uin);
    11791210                        g_free(message);
     
    11941225
    11951226                        strip_linefeed(message);
    1196                         imcb_buddy_msg(ic, uin, message, 0, 0);
     1227                        imcb_buddy_msg(ic, normalize(uin), message, 0, 0);
    11971228                        g_free(uin);
    11981229                        g_free(m);
     
    14691500
    14701501        for (i = 0; i < count; i++)
    1471                 imcb_chat_add_buddy(c->cnv, info[i].sn);
     1502                imcb_chat_add_buddy(c->cnv, normalize(info[i].sn));
    14721503
    14731504        return 1;
     
    14921523
    14931524        for (i = 0; i < count; i++)
    1494                 imcb_chat_remove_buddy(c->cnv, info[i].sn, NULL);
     1525                imcb_chat_remove_buddy(c->cnv, normalize(info[i].sn), NULL);
    14951526
    14961527        return 1;
     
    15431574        tmp = g_malloc(BUF_LONG);
    15441575        g_snprintf(tmp, BUF_LONG, "%s", msg);
    1545         imcb_chat_msg(ccon->cnv, info->sn, tmp, 0, 0);
     1576        imcb_chat_msg(ccon->cnv, normalize(info->sn), tmp, 0, 0);
    15461577        g_free(tmp);
    15471578
     
    17561787                        g_snprintf(sender, sizeof(sender), "%u", msg->sender);
    17571788                        strip_linefeed(dialog_msg);
    1758                         imcb_buddy_msg(ic, sender, dialog_msg, 0, t);
     1789                        imcb_buddy_msg(ic, normalize(sender), dialog_msg, 0, t);
    17591790                        g_free(dialog_msg);
    17601791                } break;
     
    17771808
    17781809                        strip_linefeed(dialog_msg);
    1779                         imcb_buddy_msg(ic, sender, dialog_msg, 0, t);
     1810                        imcb_buddy_msg(ic, normalize(sender), dialog_msg, 0, t);
    17801811                        g_free(dialog_msg);
    17811812                        g_free(m);
     
    20152046        struct aim_ssi_item *curitem;
    20162047        int tmp;
     2048        char *nrm;
    20172049
    20182050        /* Add from server list to local list */
    20192051        tmp = 0;
    20202052        for (curitem=sess->ssi.items; curitem; curitem=curitem->next) {
     2053                nrm = curitem->name ? normalize(curitem->name) : NULL;
     2054               
    20212055                switch (curitem->type) {
    20222056                        case 0x0000: /* Buddy */
    2023                                 if ((curitem->name) && (!imcb_find_buddy(ic, curitem->name))) {
     2057                                if ((curitem->name) && (!imcb_find_buddy(ic, nrm))) {
    20242058                                        char *realname = NULL;
    20252059
     
    20272061                                                    realname = aim_gettlv_str(curitem->data, 0x0131, 1);
    20282062                                               
    2029                                         imcb_add_buddy(ic, curitem->name, NULL);
     2063                                        imcb_add_buddy(ic, nrm, NULL);
    20302064                                       
    20312065                                        if (realname) {
    2032                                                 imcb_buddy_nick_hint(ic, curitem->name, realname);
    2033                                                 imcb_rename_buddy(ic, curitem->name, realname);
     2066                                                imcb_buddy_nick_hint(ic, nrm, realname);
     2067                                                imcb_rename_buddy(ic, nrm, realname);
    20342068                                                g_free(realname);
    20352069                                        }
     
    20432077                                        if (!list) {
    20442078                                                char *name;
    2045                                                 name = g_strdup(normalize(curitem->name));
     2079                                                name = g_strdup(nrm);
    20462080                                                ic->permit = g_slist_append(ic->permit, name);
    20472081                                                tmp++;
     
    20562090                                        if (!list) {
    20572091                                                char *name;
    2058                                                 name = g_strdup(normalize(curitem->name));
     2092                                                name = g_strdup(nrm);
    20592093                                                ic->deny = g_slist_append(ic->deny, name);
    20602094                                                tmp++;
     
    21182152                        if( st == 0x00 )
    21192153                        {
    2120                                 imcb_add_buddy( sess->aux_data, list, NULL );
     2154                                imcb_add_buddy( sess->aux_data, normalize(list), NULL );
    21212155                        }
    21222156                        else if( st == 0x0E )
     
    24482482        if(type2 == 0x0002) {
    24492483                /* User is typing */
    2450                 imcb_buddy_typing(ic, sn, OPT_TYPING);
     2484                imcb_buddy_typing(ic, normalize(sn), OPT_TYPING);
    24512485        }
    24522486        else if (type2 == 0x0001) {
    24532487                /* User has typed something, but is not actively typing (stale) */
    2454                 imcb_buddy_typing(ic, sn, OPT_THINKING);
     2488                imcb_buddy_typing(ic, normalize(sn), OPT_THINKING);
    24552489        }
    24562490        else {
    24572491                /* User has stopped typing */
    2458                 imcb_buddy_typing(ic, sn, 0);
     2492                imcb_buddy_typing(ic, normalize(sn), 0);
    24592493        }
    24602494       
     
    25882622}
    25892623
    2590 void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv)
    2591 {
     2624void oscar_accept_chat(void *data)
     2625{
     2626        struct aim_chat_invitation * inv = data;
     2627       
    25922628        oscar_chat_join(inv->ic, inv->name, NULL, NULL);
    25932629        g_free(inv->name);
     
    25952631}
    25962632
    2597 void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv)
    2598 {
     2633void oscar_reject_chat(void *data)
     2634{
     2635        struct aim_chat_invitation * inv = data;
     2636       
    25992637        g_free(inv->name);
    26002638        g_free(inv);
  • protocols/yahoo/libyahoo2.c

    r9730d72 r6738a67  
    6969#ifdef __MINGW32__
    7070# include <winsock2.h>
    71 # define write(a,b,c) send(a,b,c,0)
    72 # define read(a,b,c)  recv(a,b,c,0)
    7371#endif
    7472
     
    381379
    382380/* call repeatedly to get the next one */
    383 /*
    384381static struct yahoo_input_data * find_input_by_id(int id)
    385382{
     
    392389        return NULL;
    393390}
    394 */
    395391
    396392static struct yahoo_input_data * find_input_by_id_and_webcam_user(int id, const char * who)
     
    737733
    738734        memcpy(data + pos, "YMSG", 4); pos += 4;
    739         pos += yahoo_put16(data + pos, 0x0a00);
     735        pos += yahoo_put16(data + pos, 0x000c);
    740736        pos += yahoo_put16(data + pos, 0x0000);
    741737        pos += yahoo_put16(data + pos, pktlen + extra_pad);
     
    797793{
    798794        struct yahoo_data *yd = find_conn_by_id(id);
     795       
    799796        if(!yd)
    800797                return;
     
    31663163
    31673164        LOG(("write callback: id=%d fd=%d data=%p", id, fd, data));
    3168         if(!yid || !yid->txqueues)
     3165        if(!yid || !yid->txqueues || !find_conn_by_id(id))
    31693166                return -2;
    31703167       
     
    33513348                                        break;
    33523349                                case 5:
    3353                                         if(cp != "\005")
     3350                                        if(strcmp(cp, "5") != 0)
    33543351                                                yct->location = cp;
    33553352                                        k = 0;
     
    38423839        }
    38433840
    3844        
    3845 /*      do {
     3841        do {
    38463842                yahoo_input_close(yid);
    3847         } while((yid = find_input_by_id(id)));*/
    3848        
     3843        } while((yid = find_input_by_id(id)));
    38493844}
    38503845
  • protocols/yahoo/yahoo.c

    r9730d72 r6738a67  
    163163        g_slist_free( yd->buddygroups );
    164164       
    165         if( yd->logged_in )
    166                 yahoo_logoff( yd->y2_id );
    167         else
    168                 yahoo_close( yd->y2_id );
     165        yahoo_logoff( yd->y2_id );
    169166       
    170167        g_free( yd );
     
    315312        struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;
    316313       
    317         yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );
     314        yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" );
    318315}
    319316
     
    454451{
    455452        struct byahoo_write_ready_data *d = data;
    456        
    457         if( !byahoo_get_ic_by_id( d->id ) )
    458                 /* WTF doesn't libyahoo clean this up? */
    459                 return FALSE;
    460453       
    461454        yahoo_write_ready( d->id, d->fd, d->data );
     
    798791}
    799792
    800 static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )
    801 {
     793static void byahoo_accept_conf( void *data )
     794{
     795        struct byahoo_conf_invitation *inv = data;
     796       
    802797        yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
    803798        imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
     
    806801}
    807802
    808 static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )
    809 {
     803static void byahoo_reject_conf( void *data )
     804{
     805        struct byahoo_conf_invitation *inv = data;
     806       
    810807        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
    811808        imcb_chat_free( inv->c );
  • protocols/yahoo/yahoo_httplib.c

    r9730d72 r6738a67  
    5151#ifdef __MINGW32__
    5252# include <winsock2.h>
    53 # define write(a,b,c) send(a,b,c,0)
    54 # define read(a,b,c)  recv(a,b,c,0)
    5553# define snprintf _snprintf
    5654#endif
  • query.c

    r9730d72 r6738a67  
    3030static query_t *query_default( irc_t *irc );
    3131
    32 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data )
     32query_t *query_add( irc_t *irc, struct im_connection *ic, char *question,
     33                    query_callback yes, query_callback no, void *data )
    3334{
    3435        query_t *q = g_new0( query_t, 1 );
     
    143144        if( ans )
    144145        {
    145                 if(q->ic)
     146                if( q->ic )
    146147                        imcb_log( q->ic, "Accepted: %s", q->question );
    147148                else
    148149                        irc_usermsg( irc, "Accepted: %s", q->question );
    149                 if(q->yes)
    150                         q->yes( q->ic ? (gpointer)q->ic : (gpointer)irc, q->data );
     150                if( q->yes )
     151                        q->yes( q->data );
    151152        }
    152153        else
    153154        {
    154                 if(q->ic)
     155                if( q->ic )
    155156                        imcb_log( q->ic, "Rejected: %s", q->question );
    156157                else
    157158                        irc_usermsg( irc, "Rejected: %s", q->question );
    158                 if(q->no)
    159                         q->no( q->ic ? (gpointer)q->ic : (gpointer)irc, q->data );
     159                if( q->no )
     160                        q->no( q->data );
    160161        }
    161162        q->data = NULL;
  • query.h

    r9730d72 r6738a67  
    2727#define _QUERY_H
    2828
     29typedef void (*query_callback) ( void *data );
     30
    2931typedef struct query
    3032{
    3133        struct im_connection *ic;
    3234        char *question;
    33         void (* yes) ( gpointer w, void *data );
    34         void (* no) ( gpointer w, void *data );
     35        query_callback yes, no;
    3536        void *data;
    3637        struct query *next;
    3738} query_t;
    3839
    39 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data );
     40query_t *query_add( irc_t *irc, struct im_connection *ic, char *question,
     41                    query_callback yes, query_callback no, void *data );
    4042void query_del( irc_t *irc, query_t *q );
    4143void query_del_by_conn( irc_t *irc, struct im_connection *ic );
  • root_commands.c

    r9730d72 r6738a67  
    205205}
    206206
     207struct cmd_account_del_data
     208{
     209        account_t *a;
     210        irc_t *irc;
     211};
     212
     213void cmd_account_del_yes( void *data )
     214{
     215        struct cmd_account_del_data *cad = data;
     216        account_t *a;
     217       
     218        for( a = cad->irc->accounts; a && a != cad->a; a = a->next );
     219       
     220        if( a == NULL )
     221        {
     222                irc_usermsg( cad->irc, "Account already deleted" );
     223        }
     224        else if( a->ic )
     225        {
     226                irc_usermsg( cad->irc, "Account is still logged in, can't delete" );
     227        }
     228        else
     229        {
     230                account_del( cad->irc, a );
     231                irc_usermsg( cad->irc, "Account deleted" );
     232        }
     233        g_free( data );
     234}
     235
     236void cmd_account_del_no( void *data )
     237{
     238        g_free( data );
     239}
     240
    207241static void cmd_account( irc_t *irc, char **cmd )
    208242{
     
    263297                else
    264298                {
    265                         account_del( irc, a );
    266                         irc_usermsg( irc, "Account deleted" );
     299                        struct cmd_account_del_data *cad;
     300                        char *msg;
     301                       
     302                        cad = g_malloc( sizeof( struct cmd_account_del_data ) );
     303                        cad->a = a;
     304                        cad->irc = irc;
     305                       
     306                        msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will "
     307                                               "also forget all your saved nicknames. If you want "
     308                                               "to change your username/password, use the `account "
     309                                               "set' command. Are you sure you want to delete this "
     310                                               "account?", a->prpl->name, a->user );
     311                        query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
     312                        g_free( msg );
    267313                }
    268314        }
     
    382428                        acc_handle = g_strdup( cmd[2] );
    383429               
     430                if( !acc_handle )
     431                {
     432                        irc_usermsg( irc, "Not enough parameters given (need %d)", 3 );
     433                        return;
     434                }
     435               
    384436                if( ( tmp = strchr( acc_handle, '/' ) ) )
    385437                {
     
    562614                        g_free( irc->mynick );
    563615                        irc->mynick = g_strdup( cmd[2] );
     616                       
     617                        if( strcmp( cmd[0], "set_rename" ) != 0 )
     618                                set_setstr( &irc->set, "root_nick", cmd[2] );
    564619                }
    565620                else if( u->send_handler == buddy_send_handler )
     
    570625                irc_usermsg( irc, "Nick successfully changed" );
    571626        }
     627}
     628
     629char *set_eval_root_nick( set_t *set, char *new_nick )
     630{
     631        irc_t *irc = set->data;
     632       
     633        if( strcmp( irc->mynick, new_nick ) != 0 )
     634        {
     635                char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL };
     636               
     637                cmd_rename( irc, cmd );
     638        }
     639       
     640        return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL;
    572641}
    573642
     
    774843                else
    775844                        irc_usermsg( irc, "%s is empty", set_name );
     845
     846                if( strchr( set_name, '/' ) )
     847                        irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." );
    776848        }
    777849        else
  • set.c

    r9730d72 r6738a67  
    357357}
    358358
    359 char *set_eval_charset( set_t *set, char *value )
    360 {
    361         GIConv cd;
    362 
    363         if ( g_strncasecmp( value, "none", 4 ) == 0 )
    364                 return value;
    365 
    366         cd = g_iconv_open( "UTF-8", value );
    367         if( cd == (GIConv) -1 )
    368                 return NULL;
    369 
    370         g_iconv_close( cd );
    371         return value;
    372 }
    373 
    374359/* possible values: never, opportunistic, manual, always */
    375360char *set_eval_otr_policy( set_t *set, char *value )
  • set.h

    r9730d72 r6738a67  
    101101char *set_eval_halfop_buddies( set_t *set, char *value );
    102102char *set_eval_voice_buddies( set_t *set, char *value );
    103 char *set_eval_charset( set_t *set, char *value );
    104103char *set_eval_otr_policy( set_t *set, char *value );
    105104
  • sock.h

    r9730d72 r6738a67  
    1616#else
    1717# include <winsock2.h>
    18 # ifndef _MSC_VER
    19 #  include <ws2tcpip.h>
    20 # endif
     18# include <ws2tcpip.h>
    2119# if !defined(BITLBEE_CORE) && defined(_MSC_VER)
    2220#   pragma comment(lib,"bitlbee.lib")
    2321# endif
    2422# include <io.h>
    25 # define read(a,b,c) recv(a,b,c,0)
    26 # define write(a,b,c) send(a,b,c,0)
    27 # define umask _umask
    28 # define mode_t int
    2923# define sock_make_nonblocking(fd) { int non_block = 1; ioctlsocket(fd, FIONBIO, &non_block); }
    3024# define sock_make_blocking(fd) { int non_block = 0; ioctlsocket(fd, FIONBIO, &non_block); }
  • storage_text.c

    r9730d72 r6738a67  
    2727#include "bitlbee.h"
    2828#include "crypting.h"
     29#ifdef _WIN32
     30# define umask _umask
     31# define mode_t int
     32#endif
     33
     34#ifndef F_OK
     35#define F_OK 0
     36#endif
    2937
    3038static void text_init (void)
  • storage_xml.c

    r9730d72 r6738a67  
    2929#include "arc.h"
    3030#include "md5.h"
     31#include <glib/gstdio.h>
     32
     33#if !GLIB_CHECK_VERSION(2,8,0)
     34/* GLib < 2.8.0 doesn't have g_access, so just use the system access(). */
     35#define g_access access
     36#endif
    3137
    3238typedef enum
     
    8086                char *nick = xml_attr( attr_names, attr_values, "nick" );
    8187                char *pass = xml_attr( attr_names, attr_values, "password" );
    82                 md5_byte_t *pass_dec = NULL;
     88                int st;
    8389               
    8490                if( !nick || !pass )
     
    8793                                     "Missing attributes for %s element", element_name );
    8894                }
    89                 else if( base64_decode( pass, &pass_dec ) != 21 )
    90                 {
     95                else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 )
     96                {
     97                        xd->pass_st = XML_PASS_WRONG;
    9198                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
    9299                                     "Error while decoding password attribute" );
    93100                }
     101                else if( st == 0 )
     102                {
     103                        if( xd->pass_st != XML_PASS_CHECK_ONLY )
     104                                xd->pass_st = XML_PASS_OK;
     105                }
    94106                else
    95107                {
    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 );
     108                        xd->pass_st = XML_PASS_WRONG;
     109                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
     110                                     "Password mismatch" );
     111                }
    125112        }
    126113        else if( xd->pass_st < XML_PASS_OK )
     
    262249static void xml_init( void )
    263250{
    264         if( access( global.conf->configdir, F_OK ) != 0 )
     251        if( g_access( global.conf->configdir, F_OK ) != 0 )
    265252                log_message( LOGLVL_WARNING, "The configuration directory `%s' does not exist. Configuration won't be saved.", global.conf->configdir );
    266         else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
     253        else if( g_access( global.conf->configdir, F_OK ) != 0 ||
     254                 g_access( global.conf->configdir, W_OK ) != 0 )
    267255                log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to `%s'.", global.conf->configdir );
    268256}
     
    391379        g_free( path2 );
    392380       
    393         if( !overwrite && access( path, F_OK ) != -1 )
     381        if( !overwrite && g_access( path, F_OK ) == 0 )
    394382                return STORAGE_ALREADY_EXISTS;
    395383       
     
    428416                int pass_len;
    429417               
    430                 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );
     418                pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 );
    431419                pass_b64 = base64_encode( pass_cr, pass_len );
    432420                g_free( pass_cr );
     
    499487static storage_status_t xml_remove( const char *nick, const char *password )
    500488{
    501         char s[512];
     489        char s[512], *lc;
    502490        storage_status_t status;
    503491
     
    506494                return status;
    507495
    508         g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".xml" );
     496        lc = g_strdup( nick );
     497        nick_lc( lc );
     498        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, lc, ".xml" );
     499        g_free( lc );
     500       
    509501        if( unlink( s ) == -1 )
    510502                return STORAGE_OTHER_ERROR;
  • tests/Makefile

    r9730d72 r6738a67  
    1313main_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 check_jabber_sasl.o check_jabber_util.o
    1616
    1717check: $(test_objs) $(addprefix ../, $(main_objs)) ../protocols/protocols.o ../lib/lib.o
  • tests/check.c

    r9730d72 r6738a67  
    6969Suite *jabber_sasl_suite(void);
    7070
     71/* From check_jabber_sasl.c */
     72Suite *jabber_util_suite(void);
     73
    7174int main (int argc, char **argv)
    7275{
     
    115118        srunner_add_suite(sr, set_suite());
    116119        srunner_add_suite(sr, jabber_sasl_suite());
     120        srunner_add_suite(sr, jabber_util_suite());
    117121        if (no_fork)
    118122                srunner_set_fork_status(sr, CK_NOFORK);
  • tests/check_arc.c

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

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

    r9730d72 r6738a67  
    55#include <string.h>
    66#include <stdio.h>
    7 #include "arc.h"
    87
    98char *sasl_get_part( char *data, char *field );
  • unix.c

    r9730d72 r6738a67  
    4242static void sighandler( int signal );
    4343
    44 int main( int argc, char *argv[], char **envp )
     44int main( int argc, char *argv[] )
    4545{
    4646        int i = 0;
     
    6969        if( global.conf->runmode == RUNMODE_INETD )
    7070        {
     71                log_link( LOGLVL_ERROR, LOGOUTPUT_IRC );
     72                log_link( LOGLVL_WARNING, LOGOUTPUT_IRC );
     73       
    7174                i = bitlbee_inetd_init();
    7275                log_message( LOGLVL_INFO, "Bitlbee %s starting in inetd mode.", BITLBEE_VERSION );
     
    7578        else if( global.conf->runmode == RUNMODE_DAEMON )
    7679        {
     80                log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );
     81                log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG );
     82
    7783                i = bitlbee_daemon_init();
    7884                log_message( LOGLVL_INFO, "Bitlbee %s starting in daemon mode.", BITLBEE_VERSION );
     
    144150        {
    145151                char *fn = ipc_master_save_state();
    146                 char **args;
    147                 int n, i;
    148152               
    149153                chdir( old_cwd );
    150154               
    151                 n = 0;
    152                 args = g_new0( char *, argc + 3 );
    153                 args[n++] = argv[0];
    154                 if( fn )
    155                 {
    156                         args[n++] = "-R";
    157                         args[n++] = fn;
    158                 }
    159                 for( i = 1; argv[i] && i < argc; i ++ )
    160                 {
    161                         if( strcmp( argv[i], "-R" ) == 0 )
    162                                 i += 2;
    163                        
    164                         args[n++] = argv[i];
    165                 }
     155                setenv( "_BITLBEE_RESTART_STATE", fn, 1 );
     156                g_free( fn );
    166157               
    167158                close( global.listen_socket );
    168159               
    169                 execve( args[0], args, envp );
     160                if( execv( argv[0], argv ) == -1 )
     161                        /* Apparently the execve() failed, so let's just
     162                           jump back into our own/current main(). */
     163                        /* Need more cleanup code to make this work. */
     164                        return 1; /* main( argc, argv ); */
    170165        }
    171166       
     
    228223        return( (double) time->tv_sec + (double) time->tv_usec / 1000000 );
    229224}
     225
     226
  • welcome.txt

    r9730d72 r6738a67  
    22
    33If you've never used BitlBee before, please do read the help information using the help command. Lots of FAQs are answered there.
    4 
    54OTR users please note: Private key files are owned by the user BitlBee is running as.
     5If you already have an account on this server, just use the identify command to identify yourself.
Note: See TracChangeset for help on using the changeset viewer.