Changeset d8d63a2


Ignore:
Timestamp:
2006-12-05T20:40:17Z (14 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
7740c4c
Parents:
f4aa393 (diff), 55078f5 (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] wilmer

Files:
9 added
1 deleted
43 edited
21 moved

Legend:

Unmodified
Added
Removed
  • Makefile

    rf4aa393 rd8d63a2  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o conf.o crypting.o help.o ini.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_text.o unix.o url.o user.o util.o
     12objects = 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_OBJS) unix.o user.o
    1313headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ini.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h url.h user.h protocols/http_client.h protocols/md5.h protocols/nogaim.h protocols/proxy.h protocols/sha.h protocols/ssl_client.h
    14 subdirs = protocols
     14subdirs = protocols lib
    1515
    1616# Expansion of variables
     
    4343
    4444distclean: clean $(subdirs)
    45         rm -f Makefile.settings config.h
     45        rm -f Makefile.settings config.h bitlbee.pc
    4646        find . -name 'DEADJOE' -o -name '*.orig' -o -name '*.rej' -o -name '*~' -exec rm -f {} \;
    4747        $(MAKE) -C test distclean
  • account.c

    rf4aa393 rd8d63a2  
    3131{
    3232        account_t *a;
     33        set_t *s;
    3334       
    3435        if( irc->accounts )
    3536        {
    3637                for( a = irc->accounts; a->next; a = a->next );
    37                 a = a->next = g_new0 ( account_t, 1 );
     38                a = a->next = g_new0( account_t, 1 );
    3839        }
    3940        else
     
    4546        a->user = g_strdup( user );
    4647        a->pass = g_strdup( pass );
     48        a->auto_connect = 1;
    4749        a->irc = irc;
    4850       
     51        s = set_add( &a->set, "auto_connect", "true", set_eval_account, a );
     52        s->flags |= ACC_SET_NOSAVE;
     53       
     54        s = set_add( &a->set, "auto_reconnect", "true", set_eval_bool, a );
     55       
     56        s = set_add( &a->set, "password", NULL, set_eval_account, a );
     57        s->flags |= ACC_SET_NOSAVE;
     58       
     59        s = set_add( &a->set, "username", NULL, set_eval_account, a );
     60        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
     61        set_setstr( &a->set, "username", user );
     62       
     63        a->nicks = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free );
     64       
     65        /* This function adds some more settings (and might want to do more
     66           things that have to be done now, although I can't think of anything. */
     67        if( prpl->acc_init )
     68                prpl->acc_init( a );
     69       
    4970        return( a );
     71}
     72
     73char *set_eval_account( set_t *set, char *value )
     74{
     75        account_t *acc = set->data;
     76       
     77        /* Double-check: We refuse to edit on-line accounts. */
     78        if( set->flags & ACC_SET_OFFLINE_ONLY && acc->gc )
     79                return NULL;
     80       
     81        if( strcmp( set->key, "username" ) == 0 )
     82        {
     83                g_free( acc->user );
     84                acc->user = g_strdup( value );
     85                return value;
     86        }
     87        else if( strcmp( set->key, "password" ) == 0 )
     88        {
     89                g_free( acc->pass );
     90                acc->pass = g_strdup( value );
     91                return NULL;    /* password shouldn't be visible in plaintext! */
     92        }
     93        else if( strcmp( set->key, "server" ) == 0 )
     94        {
     95                g_free( acc->server );
     96                if( *value )
     97                        acc->server = g_strdup( value );
     98                else
     99                        acc->server = NULL;
     100                return value;
     101        }
     102        else if( strcmp( set->key, "auto_connect" ) == 0 )
     103        {
     104                if( !is_bool( value ) )
     105                        return NULL;
     106               
     107                acc->auto_connect = bool2int( value );
     108                return value;
     109        }
     110       
     111        return NULL;
    50112}
    51113
     
    68130                        for( a = irc->accounts; a; a = a->next )
    69131                                if( a->prpl == proto &&
    70                                     a->prpl->cmp_buddynames( handle, a->user ) == 0 )
     132                                    a->prpl->handle_cmp( handle, a->user ) == 0 )
    71133                                        ret = a;
    72134                }
     
    129191                        }
    130192                       
     193                        while( a->set )
     194                                set_del( &a->set, a->set->key );
     195                       
     196                        g_hash_table_destroy( a->nicks );
     197                       
    131198                        g_free( a->user );
    132199                        g_free( a->pass );
     
    142209void account_on( irc_t *irc, account_t *a )
    143210{
    144         struct aim_user *u;
    145        
    146211        if( a->gc )
    147212        {
     
    152217        cancel_auto_reconnect( a );
    153218       
    154         u = g_new0 ( struct aim_user, 1 );
    155         u->irc = irc;
    156         u->prpl = a->prpl;
    157         strncpy( u->username, a->user, sizeof( u->username ) - 1 );
    158         strncpy( u->password, a->pass, sizeof( u->password ) - 1 );
    159         if( a->server) strncpy( u->proto_opt[0], a->server, sizeof( u->proto_opt[0] ) - 1 );
    160        
    161         a->gc = (struct gaim_connection *) u; /* Bit hackish :-/ */
    162219        a->reconnect = 0;
    163        
    164         a->prpl->login( u );
     220        a->prpl->login( a );
    165221}
    166222
  • account.h

    rf4aa393 rd8d63a2  
    3434        char *server;
    3535       
     36        int auto_connect;
    3637        int reconnect;
     38       
     39        set_t *set;
     40        GHashTable *nicks;
    3741       
    3842        struct irc *irc;
     
    4751void account_off( irc_t *irc, account_t *a );
    4852
     53char *set_eval_account( set_t *set, char *value );
     54
     55#define ACC_SET_NOSAVE          1
     56#define ACC_SET_OFFLINE_ONLY    2
     57#define ACC_SET_ONLINE_ONLY     4
     58
    4959#endif
  • bitlbee.c

    rf4aa393 rd8d63a2  
    3939{
    4040#ifdef IPV6
    41         struct sockaddr_in6 listen_addr;
    42 #else
     41        int use_ipv6 = 1;
     42        struct sockaddr_in6 listen_addr6;
     43#endif
    4344        struct sockaddr_in listen_addr;
    44 #endif
    4545        int i;
    4646        FILE *fp;
     
    4949        log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG );
    5050       
    51         global.listen_socket = socket( AF_INETx, SOCK_STREAM, 0 );
     51#ifdef IPV6
     52        if( ( global.listen_socket = socket( AF_INET6, SOCK_STREAM, 0 ) ) == -1 )
     53        {
     54                use_ipv6 = 0;
     55#endif
     56                global.listen_socket = socket( AF_INET, SOCK_STREAM, 0 );
     57#ifdef IPV6
     58        }
     59#endif
    5260        if( global.listen_socket == -1 )
    5361        {
     
    6169       
    6270#ifdef IPV6
    63         listen_addr.sin6_family = AF_INETx;
    64         listen_addr.sin6_port = htons( global.conf->port );
    65         i = inet_pton( AF_INETx, ipv6_wrap( global.conf->iface ), &listen_addr.sin6_addr );
    66 #else
    67         listen_addr.sin_family = AF_INETx;
    68         listen_addr.sin_port = htons( global.conf->port );
    69         i = inet_pton( AF_INETx, global.conf->iface, &listen_addr.sin_addr );
     71        listen_addr6.sin6_family = AF_INET6;
     72        listen_addr6.sin6_port = htons( global.conf->port );
     73        if( ( i = inet_pton( AF_INET6, ipv6_wrap( global.conf->iface ), &listen_addr6.sin6_addr ) ) != 1 )
     74        {
     75                /* Forget about IPv6 in this function. */
     76                use_ipv6 = 0;
     77#endif
     78                listen_addr.sin_family = AF_INET;
     79                listen_addr.sin_port = htons( global.conf->port );
     80                if( strcmp( global.conf->iface, "::" ) == 0 )
     81                        i = inet_pton( AF_INET, "0.0.0.0", &listen_addr.sin_addr );
     82                else
     83                        i = inet_pton( AF_INET, global.conf->iface, &listen_addr.sin_addr );
     84#ifdef IPV6
     85        }
    7086#endif
    7187       
     
    7692        }
    7793       
    78         i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) );
     94#ifdef IPV6
     95        if( !use_ipv6 || ( i = bind( global.listen_socket, (struct sockaddr *) &listen_addr6, sizeof( listen_addr6 ) ) ) == -1 )
     96#endif
     97                i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) );
    7998        if( i == -1 )
    8099        {
     
    291310                        irc_t *irc;
    292311                       
     312                        /* Since we're fork()ing here, let's make sure we won't
     313                           get the same random numbers as the parent/siblings. */
     314                        srand( time( NULL ) ^ getpid() );
     315                       
    293316                        /* Close the listening socket, we're a client. */
    294317                        close( global.listen_socket );
  • bitlbee.h

    rf4aa393 rd8d63a2  
    124124#include "commands.h"
    125125#include "account.h"
     126#include "nick.h"
    126127#include "conf.h"
    127128#include "log.h"
     
    130131#include "query.h"
    131132#include "sock.h"
    132 #include "util.h"
     133#include "misc.h"
    133134#include "proxy.h"
    134135
  • conf.c

    rf4aa393 rd8d63a2  
    3434#include "ipc.h"
    3535
    36 #include "protocols/proxy.h"
     36#include "proxy.h"
    3737
    3838char *CONF_FILE;
     
    5555        conf->nofork = 0;
    5656        conf->verbose = 0;
    57         conf->primary_storage = "text";
     57        conf->primary_storage = "xml";
     58        conf->migrate_storage = g_strsplit( "text", ",", -1 );
    5859        conf->runmode = RUNMODE_INETD;
    5960        conf->authmode = AUTHMODE_OPEN;
     
    322323                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
    323324                {
    324                         set_t *s = set_find( irc, ini->key );
     325                        set_t *s = set_find( &irc->set, ini->key );
    325326                       
    326327                        if( s )
  • configure

    rf4aa393 rd8d63a2  
    3232
    3333events=glib
     34ldap=0
    3435ssl=auto
    3536
    3637arch=`uname -s`
    3738cpu=`uname -m`
     39
     40GLIB_MIN_VERSION=2.4
    3841
    3942echo BitlBee configure
     
    6871
    6972--ipv6=0/1      IPv6 socket support                     $ipv6
     73
     74--ldap=0/1/auto LDAP support                            $ldap
    7075
    7176--events=...    Event handler (glib, libevent)          $events
     
    143148fi
    144149
    145 echo CFLAGS+=-I`pwd` -I`pwd`/protocols -I. >> Makefile.settings
     150echo CFLAGS+=-I`pwd` -I`pwd`/lib -I`pwd`/protocols -I. >> Makefile.settings
    146151
    147152echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings
    148153
    149154if [ -n "$CC" ]; then
    150         echo "CC=$CC" >> Makefile.settings;
     155        CC=$CC
    151156elif type gcc > /dev/null 2> /dev/null; then
    152         echo "CC=gcc" >> Makefile.settings;
     157        CC=gcc
    153158elif type cc > /dev/null 2> /dev/null; then
    154         echo "CC=cc" >> Makefile.settings;
     159        CC=cc
    155160else
    156161        echo 'Cannot find a C compiler, aborting.'
    157162        exit 1;
    158163fi
     164
     165echo "CC=$CC" >> Makefile.settings;
    159166
    160167if [ -n "$LD" ]; then
     
    172179
    173180if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG glib-2.0; then
    174         cat<<EOF>>Makefile.settings
     181        if $PKG_CONFIG glib-2.0 --atleast-version=$GLIB_MIN_VERSION; then
     182                cat<<EOF>>Makefile.settings
    175183EFLAGS+=`$PKG_CONFIG --libs glib-2.0 gmodule-2.0`
    176184CFLAGS+=`$PKG_CONFIG --cflags glib-2.0 gmodule-2.0`
    177185EOF
    178 else
     186        else
     187                echo
     188                echo 'Found glib2 '`$PKG_CONFIG glib-2.0 --modversion`', but version '$GLIB_MIN_VERSION' or newer is required.'
     189                exit 1
     190        fi
     191else
     192        echo
    179193        echo 'Cannot find glib2 development libraries, aborting. (Install libglib2-dev?)'
    180         exit 1;
     194        exit 1
    181195fi
    182196
     
    234248}
    235249
    236 if [ "$msn" = 1 -o "$jabber" = 1 ]; then
    237         if [ "$ssl" = "auto" ]; then
    238                 detect_gnutls
    239                 if [ "$ret" = "0" ]; then
    240                         detect_nss
    241                 fi;
    242         elif [ "$ssl" = "gnutls" ]; then
    243                 detect_gnutls;
    244         elif [ "$ssl" = "nss" ]; then
    245                 detect_nss;
    246         elif [ "$ssl" = "openssl" ]; then
     250detect_ldap()
     251{
     252        TMPFILE=`mktemp`
     253        if $CC -o $TMPFILE -shared -lldap 2>/dev/null >/dev/null; then
     254                cat<<EOF>>Makefile.settings
     255EFLAGS+=-lldap
     256CFLAGS+=
     257EOF
     258                ldap=1
     259                rm -f $TMPFILE
     260                ret=1
     261        else
     262                ldap=0
     263                ret=0
     264        fi
     265}
     266
     267if [ "$ssl" = "auto" ]; then
     268        detect_gnutls
     269        if [ "$ret" = "0" ]; then
     270                detect_nss
     271        fi
     272elif [ "$ssl" = "gnutls" ]; then
     273        detect_gnutls
     274elif [ "$ssl" = "nss" ]; then
     275        detect_nss
     276elif [ "$ssl" = "openssl" ]; then
     277        echo
     278        echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
     279        echo 'install of OpenSSL (including devel/header files) before reporting'
     280        echo 'compilation problems.'
     281        echo
     282        echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
     283        echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
     284        echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
     285        echo 'part of the operating system, which makes it GPL-compatible.'
     286        echo
     287        echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
     288        echo '                    http://www.gnome.org/~markmc/openssl-and-the-gpl.html'
     289        echo
     290        echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
     291        echo 'probably illegal. If you want to create and distribute a binary BitlBee'
     292        echo 'package, you really should use GnuTLS or NSS instead.'
     293        echo
     294        echo 'Also, the OpenSSL license requires us to say this:'
     295        echo ' *    "This product includes software developed by the OpenSSL Project'
     296        echo ' *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"'
     297       
     298        echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings
     299       
     300        ret=1
     301elif [ "$ssl" = "bogus" ]; then
     302        echo
     303        echo 'Using bogus SSL code. This means some features will not work properly.'
     304       
     305        ## Yes, you, at the console! How can you authenticate if you don't have any SSL!?
     306        if [ "$msn" = "1" ]; then
    247307                echo
    248                 echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
    249                 echo 'install of OpenSSL (including devel/header files) before reporting'
    250                 echo 'compilation problems.'
    251                 echo
    252                 echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
    253                 echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
    254                 echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
    255                 echo 'part of the operating system, which makes it GPL-compatible.'
    256                 echo
    257                 echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
    258                 echo '                    http://www.gnome.org/~markmc/openssl-and-the-gpl.html'
    259                 echo
    260                 echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
    261                 echo 'probably illegal. If you want to create and distribute a binary BitlBee'
    262                 echo 'package, you really should use GnuTLS or NSS instead.'
    263                 echo
    264                 echo 'Also, the OpenSSL license requires us to say this:'
    265                 echo ' *    "This product includes software developed by the OpenSSL Project'
    266                 echo ' *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"'
    267                
    268                 echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings
    269                
    270                 ret=1;
    271         elif [ "$ssl" = "bogus" ]; then
    272                 echo
    273                 echo 'Using bogus SSL code. This will not make the MSN module work, but it will'
    274                 echo 'allow you to use the Jabber module - although without working SSL support.'
    275                
    276                 ret=1;
    277         else
    278                 echo
    279                 echo 'ERROR: Unknown SSL library specified.'
    280                 exit 1;
    281         fi
    282        
    283         if [ "$ret" = "0" ]; then
    284                 echo
    285                 echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
    286                 echo '       This is necessary for MSN and full Jabber support. To continue,'
    287                 echo '       install a suitable SSL library or disable MSN support (--msn=0).'
    288                 echo '       If you want Jabber without SSL support you can try --ssl=bogus.'
    289                
    290                 exit 1;
    291         fi;
    292        
    293         echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
    294 fi
     308                echo 'Real SSL support is necessary for MSN authentication, will build without'
     309                echo 'MSN protocol support.'
     310                msn=0
     311        fi
     312       
     313        ret=1
     314else
     315        echo
     316        echo 'ERROR: Unknown SSL library specified.'
     317        exit 1
     318fi
     319
     320if [ "$ret" = "0" ]; then
     321        echo
     322        echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
     323        echo '       Please note that this script doesn'\''t have detection code for OpenSSL,'
     324        echo '       so if you want to use that, you have to select it by hand. If you don'\''t'
     325        echo '       need SSL support, you can select the "bogus" SSL library. (--ssl=bogus)'
     326       
     327        exit 1
     328fi;
     329
     330echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
     331
     332STORAGES="text xml"
     333
     334if [ "$ldap" = "auto" ]; then
     335        detect_ldap
     336fi
     337
     338if [ "$ldap" = 0 ]; then
     339        echo "#undef WITH_LDAP" >> config.h
     340elif [ "$ldap" = 1 ]; then
     341        echo "#define WITH_LDAP 1" >> config.h
     342        STORAGES="$STORAGES ldap"
     343fi
     344
     345for i in $STORAGES; do
     346        STORAGE_OBJS="$STORAGE_OBJS storage_$i.o"
     347done
     348echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings
    295349
    296350if [ "$strip" = 0 ]; then
     
    306360        elif type strip > /dev/null 2> /dev/null; then
    307361                echo "STRIP=strip" >> Makefile.settings;
    308         elif /bin/test -x /usr/ccs/bin/strip; then
    309                 echo "STRIP=/usr/ccs/bin/strip" >> Makefile.settings;
    310362        else
    311363                echo
     
    391443if [ "$protocols" = "PROTOCOLS = " ]; then
    392444        echo "WARNING: You haven't selected any communication protocol to compile!"
    393         echo "         Bitlbee will run, but you will be unable to connect to IM servers!"
     445        echo "         BitlBee will run, but you will be unable to connect to IM servers!"
    394446fi
    395447
     
    426478
    427479if [ "$debug" = "1" ]; then
    428         echo '  Debugging enabled.';
    429 else
    430         echo '  Debugging disabled.';
     480        echo '  Debugging enabled.'
     481else
     482        echo '  Debugging disabled.'
    431483fi
    432484
    433485if [ "$strip" = "1" ]; then
    434         echo '  Binary stripping enabled.';
    435 else
    436         echo '  Binary stripping disabled.';
    437 fi
    438 
    439 echo '  Using event handler: '$events;
    440 echo '  Using SSL library: '$ssl;
    441 
    442 #if [ "$flood" = "0" ]; then
    443 #       echo '  Flood protection disabled.';
    444 #else
    445 #       echo '  Flood protection enabled.';
    446 #fi
     486        echo '  Binary stripping enabled.'
     487else
     488        echo '  Binary stripping disabled.'
     489fi
     490
     491echo '  Using event handler: '$events
     492echo '  Using SSL library: '$ssl
     493echo '  Building with these storage backends: '$STORAGES
    447494
    448495if [ -n "$protocols" ]; then
    449         echo '  Building with these protocols:' $protocols;
    450 else
    451         echo '  Building without IM-protocol support. We wish you a lot of fun...';
    452 fi
     496        echo '  Building with these protocols:' $protocols
     497else
     498        echo '  Building without IM-protocol support. We wish you a lot of fun...'
     499fi
  • doc/CHANGES

    rf4aa393 rd8d63a2  
     1Version x.x:
     2- Added ForkDaemon mode next to the existing Daemon- and inetd modes. With
     3  ForkDaemon you can run BitlBee as a stand-alone daemon and every connection
     4  will run in its own process. No more need to configure inetd, and still you
     5  don't get the stability problems BitlBee unfortunately still has in ordinary
     6  (one-process) daemon mode.
     7- Added inter-process/connection communication. This made it possible to
     8  implement some IRC operator features like WALLOPs, KILL, DIE, REHASH and
     9  more.
     10- Added hooks for using libevent instead of GLib for event handling. This
     11  should improve scalability, although this won't really be useful yet because
     12  the one-process daemon mode is not reliable enough.
     13- BitlBee now makes the buddy quits when doing "account off" look like a
     14  netsplit. Modern IRC clients show this in a different, more compact way.
     15- GLib 1.x compatibility was dropped. BitlBee now requires GLib 2.4 or newer.
     16  This allows us to use more GLib features (like the XML parser). By now GLib
     17  1.x is so old that supporting it really isn't necessary anymore.
     18- Many, many, MANY little changes, improvements, fixes. Using non-blocking
     19  I/O as much as possible, fixed lots of little bugs (including bugs that
     20  affected daemon mode stability). See the bzr logs for more information.
     21- Most important change: New file format for user data (accounts, nicks and
     22  settings). Migration to the new format should happen transparently,
     23  BitlBee will read the old files and once you quit/save it will save in the
     24  new format. It is recommended to delete the old files (BitlBee doesn't do
     25  this automatically, it will just ignore them) since they won't be used
     26  anymore (and since the old file format is a security risk). Some advantages
     27  of this file format switch:
     28  * Safer format, since the identify-password is now salted before generating
     29    a checksum. This way one can't use MD5 reverse lookup databases to crack
     30    passwords. Also, the IM-account passwords are encrypted using RC4 instead
     31    of the simple obfuscation scheme which BitlBee used so far.
     32  * Easier to extend than the previous format (at least the .nicks format was
     33    horribly limited).
     34  * Nicknames for buddies are now saved per-account instead of per-protocol.
     35    So far having one buddy on multiple accounts of the same protocol was a
     36    problem because the nicks generated for the two "instances" of this buddy
     37    were very unpredictable.
     38    NOTE: This also means that "account del" removes not just the account,
     39    BUT ALSO ALL NICKNAMES! If you're changing IM accounts and don't want to
     40    lose the nicknames, you can now use "account set" to change the username
     41    and password for the existing connection.
     42  * Per-account settings (see the new "account set" command).
     43
     44Version 1.0.3:
     45- Fixed ugliness in block/allow list commands (still not perfect though, the
     46  list is empty or not up-to-date for most protocols).
     47- OSCAR module doesn't send the ICQ web-aware flag anymore, which seems to
     48  get rid of a lot of ICQ spam.
     49- added show_got_added(), BitlBee asks you, after authorizing someone, if you
     50  want to add him/her to your list too.
     51- add -tmp, mainly convenient if you want to talk to people who are not in
     52  your list.
     53- Fixed ISON command, should work better with irssi now.
     54- Fixed compilation with tcc.
     55- Fixed xinetd-file.
     56- Misc. (crash)bug fixes, including one in the root command parsing that
     57  caused mysterious error messages sometimes.
     58
     59Finished 24 Jun 2006 (Happy 4th birthday, BitlBee!)
     60
     61Version 1.0.2:
     62- Pieces of code cleanup, fixes for possible problems in error checking.
     63- Fixed an auto-reconnect cleanup problem that caused crashes in daemon mode.
     64- /AWAY in daemon mode now doesn't set the away state for every connection
     65  anymore.
     66- Fixed a crash-bug on empty help subjects.
     67- Jabber now correctly sets the current away state when connecting.
     68- Added Invisible and Hidden to the away state alias list, invisible mode
     69  should be pretty usable now.
     70- Fixed handling of iconv(): It's now done for everything that goes between
     71  BitlBee and the IRC client, instead of doing it (almost) every time
     72  something goes to or come from the IM-modules. Should've thought about
     73  that before. :-)
     74- When cleaning up MSN switchboards with unsent msgs, it now also says which
     75  contact those messages were meant for.
     76- You can now use the block and allow commands to see your current block/
     77  allow list.
     78
     79Finished 1 Apr 2006
     80
     81Version 1.0.1:
     82- Support for AIM groupchats.
     83- Improved typing notification support for at least AIM.
     84- BitlBee sends a 005 reply when logging in, this informs modern IRC clients
     85  of some of BitlBee's capabilities. This might also solve problems some
     86  people were having with the new control channel name.
     87- MSN switchboards are now properly reset when talking to a person who is
     88  offline. This fixes problems with messages to MSN people that sometimes
     89  didn't arrive.
     90- Fixed one of the problems that made BitlBee show online Jabber people as
     91  offline.
     92- Fixed problems with commas in MSN passwords.
     93- Added some consts for read-only data, which should make the BitlBee per-
     94  process memory footprint a bit smaller.
     95- Other bits of code cleanup.
     96
     97Finished 14 Jan 2006
     98
    199Version 1.0:
    2100- Removed some crashy debugging code.
  • doc/README

    rf4aa393 rd8d63a2  
    155155====================
    156156
    157 BitlBee stores the accounts and settings (not your contact list though) in
    158 some sort of encrypted/obfuscated format.
    159 
    160 *** THIS IS NOT A SAFE FORMAT! ***
    161 
    162 You should still make sure the rights to the configuration directory and
    163 files are set so that only root and the BitlBee user can read/write them.
    164 
    165 This format is not to prevent malicicous users from running with your
    166 passwords, but to prevent accidental glimpses of the administrators to cause
    167 any harm. You have no choice but to trust root though.
     157There used to be a note here about the simple obfuscation method used to
     158make the passwords in the configuration files unreadable. However, BitlBee
     159now uses a better format (and real encryption (salted MD5 and RC4)) to store
     160the passwords. This means that people who somehow get their hands on your
     161configuration files can't easily extract your passwords from them anymore.
     162
     163However, once you log into the BitlBee server and send your password, an
     164intruder with tcpdump can still read your passwords. This can't really be
     165avoided, of course. The new format is a lot more reliable (because it can't
     166be cracked with just very basic crypto analysis anymore), but you still have
     167to be careful. The main extra protection offered by the new format is that
     168the files can only be cracked with some help from the user (by sending the
     169password at login time).
     170
     171So if you run a public server, it's most important that you don't give root
     172access to people who like to play with tcpdump. Also, it's a good idea to
     173delete all *.nicks/*.accounts files as soon as BitlBee converted them to the
     174new format (which happens as soon as the user logs in, it can't be done
     175automatically because it needs the password for that account). You won't
     176need them anymore (unless you want to switch back to an older BitlBee
     177version) and they only make it easier for others to crack your passwords.
    168178
    169179
     
    192202        BitlBee - An IRC to other chat networks gateway
    193203                  <http://www.bitlbee.org/>
    194         Copyright (C) 2002-2005  Wilmer van der Gaast <wilmer@gaast.net>
     204        Copyright (C) 2002-2006  Wilmer van der Gaast <wilmer@gaast.net>
    195205                                 and others
  • doc/user-guide/Makefile

    rf4aa393 rd8d63a2  
    2828        xsltproc --xinclude --output $@ docbook.xsl $<
    2929
    30 help.txt: help.xml help.xsl
     30help.txt: help.xml help.xsl commands.xml misc.xml quickstart.xml
    3131        xsltproc --stringparam extraparanewline "$(EXTRAPARANEWLINE)" --xinclude help.xsl $< | perl -0077 -pe 's/\n\n%/\n%/s; s/_b_/\002/g;' > $@
    3232
  • doc/user-guide/commands.xml

    rf4aa393 rd8d63a2  
    1111
    1212                        <para>
    13                                 Available actions: add, del, list, on, off. See <emphasis>help account &lt;action&gt;</emphasis> for more information.
     13                                Available actions: add, del, list, on, off and set. See <emphasis>help account &lt;action&gt;</emphasis> for more information.
    1414                        </para>
    1515
     
    2626                       
    2727                        <bitlbee-command name="jabber">
    28                                 <syntax>account add jabber &lt;handle&gt; &lt;password&gt; [&lt;servertag&gt;]</syntax>
     28                                <syntax>account add jabber &lt;handle@server.tld&gt; &lt;password&gt; [&lt;servertag&gt;]</syntax>
    2929
    3030                                <description>
    3131                                        <para>
    32                                                 Note that the servertag argument is optional. You only have to use it if the part after the @ in your handle isn't the hostname of your Jabber server, or if you want to use SSL/connect to a non-standard port number. The format is simple: [&lt;servername&gt;[:&lt;portnumber&gt;][:ssl]]. For example, this is how you can connect to Google Talk:
     32                                                Note that the servertag argument is optional. You only have to use it if the part after the @ in your handle isn't the hostname of your Jabber server, or if you want to use SSL/connect to a non-standard port number. The format is simple: [&lt;servername&gt;[:&lt;portnumber&gt;][:ssl]].
     33                                        </para>
     34                                </description>
     35
     36                                <description>
     37                                        <para>
     38                                                Google Talk uses the Jabber protocol. Please note that Google talk is SSL-only, but officially reachable over both port 5222 and 5223. Usually BitlBee users have to connect via port 5223, for example like this:
    3339                                        </para>
    3440                                </description>
     
    3844                                        <ircline nick="root">Account successfully added</ircline>
    3945                                </ircexample>
    40 
    41                                 <description>
    42                                         <para>
    43                                                 Note that Google talk is SSL-only, but officially reachable over both port 5222 and 5223. However, for some people only port 5222 works, for some people only 5223. This is something you'll have to try out.
    44                                         </para>
    45                                 </description>
    4646                        </bitlbee-command>
    4747
    4848                        <bitlbee-command name="msn">
    49                                 <syntax>account add msn &lt;handle&gt; &lt;password&gt;</syntax>
     49                                <syntax>account add msn &lt;handle@server.tld&gt; &lt;password&gt;</syntax>
    5050
    5151                                <description>
     
    103103                        <description>
    104104                                <para>
    105                                         This command will try to log into the specified account. If no account is specified, BitlBee will log into all the accounts. (Including accounts awaiting a reconnection)
     105                                        This command will try to log into the specified account. If no account is specified, BitlBee will log into all the accounts that have the auto_connect flag set.
    106106                                </para>
    107107
     
    118118                        <description>
    119119                                <para>
    120                                         This command disconnects the connection for the specified account. If no account is specified, BitlBee will deactivate all active accounts. (Including accounts awaiting a reconnection)
     120                                        This command disconnects the connection for the specified account. If no account is specified, BitlBee will deactivate all active accounts and cancel all pending reconnects.
    121121                                </para>
    122122
     
    133133                                <para>
    134134                                        This command gives you a list of all the accounts known by BitlBee, including the numbers you'll need for most account commands.
     135                                </para>
     136                        </description>
     137                </bitlbee-command>
     138
     139                <bitlbee-command name="set">
     140                        <syntax>account set &lt;account id&gt;</syntax>
     141                        <syntax>account set &lt;account id&gt;/&lt;setting&gt;</syntax>
     142                        <syntax>account set &lt;account id&gt;/&lt;setting&gt; &lt;value&gt;</syntax>
     143
     144                        <description>
     145                                <para>
     146                                        This account can be used to change various settings for IM accounts. For all protocols, this command can be used to change the handle or the password BitlBee uses to log in and if it should be logged in automatically. Some protocols have additional settings. You can see the settings available for a connection by typing <emphasis>account set &lt;account id&gt;</emphasis>.
     147                                </para>
     148                               
     149                                <para>
     150                                        For more infomation about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
     151                                </para>
     152                               
     153                                <para>
     154                                        The account ID can be a number (see <emphasis>account list</emphasis>), the protocol name or (part of) the screenname, as long as it matches only one connection.
    135155                                </para>
    136156                        </description>
     
    276296        </bitlbee-command>
    277297
    278         <bitlbee-setting name="charset" type="string">
     298        <bitlbee-setting name="auto_connect" type="boolean" scope="both">
     299                <default>true</default>
     300
     301                <description>
     302                        <para>
     303                                With this option enabled, when you identify BitlBee will automatically connect to your accounts, with this disabled it will not do this.
     304                        </para>
     305                       
     306                        <para>
     307                                This setting can also be changed for specific accounts using the <emphasis>account set</emphasis> command. (However, these values will be ignored if the global <emphasis>auto_connect</emphasis> setting is disabled!)
     308                        </para>
     309                </description>
     310        </bitlbee-setting>
     311
     312        <bitlbee-setting name="auto_reconnect" type="boolean" scope="both">
     313                <default>false</default>
     314
     315                <description>
     316                        <para>
     317                                If an IM-connections breaks, you're supposed to bring it back up yourself. Having BitlBee do this automatically might not always be a good idea, for several reasons. If you want the connections to be restored automatically, you can enable this setting.
     318                        </para>
     319
     320                        <para>
     321                                See also the <emphasis>auto_reconnect_delay</emphasis> setting.
     322                        </para>
     323
     324                        <para>
     325                                This setting can also be changed for specific accounts using the <emphasis>account set</emphasis> command. (However, these values will be ignored if the global <emphasis>auto_reconnect</emphasis> setting is disabled!)
     326                        </para>
     327                </description>
     328        </bitlbee-setting>
     329
     330        <bitlbee-setting name="auto_reconnect_delay" type="integer" scope="global">
     331                <default>300</default>
     332
     333                <description>
     334                        <para>
     335                                Tell BitlBee after how many seconds it should attempt to bring an IM-connection back up after a crash. It's not a good idea to set this value very low, it will cause too much useless traffic when an IM-server is down for a few hours.
     336                        </para>
     337
     338                        <para>
     339                                See also the <emphasis>auto_reconnect</emphasis> setting.
     340                        </para>
     341                </description>
     342        </bitlbee-setting>
     343
     344        <bitlbee-setting name="away_devoice" type="boolean" scope="global">
     345                <default>true</default>
     346
     347                <description>
     348                        <para>
     349                                With this option enabled, the root user devoices people when they go away (just away, not offline) and gives the voice back when they come back. You might dislike the voice-floods you'll get if your contact list is huge, so this option can be disabled.
     350                        </para>
     351                </description>
     352        </bitlbee-setting>
     353
     354        <bitlbee-setting name="buddy_sendbuffer" type="boolean" scope="global">
     355                <default>false</default>
     356
     357                <description>
     358                        <para>
     359                                By default, when you send a message to someone, BitlBee forwards this message to the user immediately. When you paste a large number of lines, the lines will be sent in separate messages, which might not be very nice to read. If you enable this setting, BitlBee will buffer your messages and wait for more data.
     360                        </para>
     361
     362                        <para>
     363                                Using the <emphasis>buddy_sendbuffer_delay</emphasis> setting you can specify the number of seconds BitlBee should wait for more data before the complete message is sent.
     364                        </para>
     365
     366                        <para>
     367                                Please note that if you remove a buddy from your list (or if the connection to that user drops) and there's still data in the buffer, this data will be lost. BitlBee will not try to send the message to the user in those cases.
     368                        </para>
     369                </description>
     370        </bitlbee-setting>
     371
     372        <bitlbee-setting name="buddy_sendbuffer_delay" type="integer" scope="global">
     373                <default>200</default>
     374
     375                <description>
     376
     377                        <para>
     378                                Tell BitlBee after how many (mili)seconds a buffered message should be sent. Values greater than 5 will be interpreted as miliseconds, 5 and lower as seconds.
     379                        </para>
     380
     381                        <para>
     382                                See also the <emphasis>buddy_sendbuffer</emphasis> setting.
     383                        </para>
     384                </description>
     385        </bitlbee-setting>
     386
     387        <bitlbee-setting name="charset" type="string" scope="global">
    279388                <default>iso8859-1</default>
    280389                <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values>
     
    292401        </bitlbee-setting>
    293402
    294         <bitlbee-setting name="private" type="boolean">
    295                 <default>True</default>
    296 
    297                 <description>
    298 
    299                         <para>
    300                                 If value is true, messages from users will appear in separate query windows. If false, messages from users will appear in the control channel.
    301                         </para>
    302 
    303                         <para>
    304                                 This setting is remembered (during one session) per-user, this setting only changes the default state. This option takes effect as soon as you reconnect.
    305                         </para>
    306                 </description>
    307         </bitlbee-setting>
    308 
    309         <bitlbee-setting name="save_on_quit" type="boolean">
    310                 <default>True</default>
    311 
    312                 <description>
    313                         <para>
    314                                 If enabled causes BitlBee to save all current settings and account details when user disconnects. This is enabled by default, and these days there's not really a reason to have it disabled anymore.
    315                         </para>
    316                 </description>
    317         </bitlbee-setting>
    318 
    319         <bitlbee-setting name="strip_html" type="boolean">
    320                 <default>True</default>
    321 
    322                 <description>
    323                         <para>
    324                                 Determines what BitlBee should do with HTML in messages. Normally this is turned on and HTML will be stripped from messages, if BitlBee thinks there is HTML.
    325                         </para>
    326                         <para>
    327                                 If BitlBee fails to detect this sometimes (most likely in AIM messages over an ICQ connection), you can set this setting to <emphasis>always</emphasis>, but this might sometimes accidentally strip non-HTML things too.
    328                         </para>
    329                 </description>
    330         </bitlbee-setting>
    331 
    332         <bitlbee-setting name="debug" type="boolean">
    333                 <default>False</default>
     403        <bitlbee-setting name="debug" type="boolean" scope="global">
     404                <default>false</default>
    334405
    335406                <description>
     
    340411        </bitlbee-setting>
    341412
    342         <bitlbee-setting name="to_char" type="string">
    343                 <default>": "</default>
    344 
    345                 <description>
    346 
    347                         <para>
    348                                 It's customary that messages meant for one specific person on an IRC channel are prepended by his/her alias followed by a colon ':'. BitlBee does this by default. If you prefer a different character, you can set it using <emphasis>set to_char</emphasis>.
    349                         </para>
    350 
    351                         <para>
    352                                 Please note that this setting is only used for incoming messages. For outgoing messages you can use ':' (colon) or ',' to separate the destination nick from the message, and this is not configurable.
    353                         </para>
    354                 </description>
    355         </bitlbee-setting>
    356 
    357         <bitlbee-setting name="typing_notice" type="boolean">
    358                 <default>False</default>
    359 
    360                 <description>
    361                         <para>
    362                                 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. ;-)
    363                         </para>
    364                 </description>
    365         </bitlbee-setting>
    366 
    367         <bitlbee-setting name="ops" type="string">
    368                 <default>both</default>
    369                 <possible-values>both, root, user, none</possible-values>
    370 
    371                 <description>
    372                         <para>
    373                                 Some people prefer themself and root to have operator status in &amp;bitlbee, other people don't. You can change these states using this setting.
    374                         </para>
    375 
    376                         <para>
    377                                 The value "both" means both user and root get ops. "root" means, well, just root. "user" means just the user. "none" means nobody will get operator status.
    378                         </para>
    379                 </description>
    380         </bitlbee-setting>
    381 
    382         <bitlbee-setting name="away_devoice" type="boolean">
    383                 <default>True</default>
    384 
    385                 <description>
    386                         <para>
    387                                 With this option enabled, the root user devoices people when they go away (just away, not offline) and gives the voice back when they come back. You might dislike the voice-floods you'll get if your contact list is huge, so this option can be disabled.
    388                         </para>
    389                 </description>
    390         </bitlbee-setting>
    391 
    392         <bitlbee-setting name="handle_unknown" type="string">
     413        <bitlbee-setting name="default_target" type="string" scope="global">
     414                <default>root</default>
     415                <possible-values>root, last</possible-values>
     416
     417                <description>
     418                        <para>
     419                                With this value set to <emphasis>root</emphasis>, lines written in the control channel without any nickname in front of them will be interpreted as commands. If you want BitlBee to send those lines to the last person you addressed in the control channel, set this to <emphasis>last</emphasis>.
     420                        </para>
     421                </description>
     422        </bitlbee-setting>
     423
     424        <bitlbee-setting name="display_name" type="string" scope="account">
     425                <description>
     426                        <para>
     427                                Currently only available for MSN connections. This setting allows you to read and change your "friendly name" for this connection. Since this is a server-side setting, it can't be changed when the account is off-line.
     428                        </para>
     429                </description>
     430        </bitlbee-setting>
     431
     432        <bitlbee-setting name="display_namechanges" type="boolean" scope="global">
     433                <default>false</default>
     434
     435                <description>
     436                        <para>
     437                                With this option enabled, root will inform you when someone in your buddy list changes his/her "friendly name".
     438                        </para>
     439                </description>
     440        </bitlbee-setting>
     441
     442        <bitlbee-setting name="handle_unknown" type="string" scope="global">
    393443                <default>root</default>
    394444                <possible-values>root, add, add_private, add_channel, ignore</possible-values>
     
    417467        </bitlbee-setting>
    418468
    419         <bitlbee-setting name="auto_connect" type="boolean">
    420                 <default>True</default>
    421 
    422                 <description>
    423                         <para>
    424                                 With this option enabled, when you identify BitlBee will automatically connect to your accounts, with this disabled it will not do this.
    425                         </para>
    426                 </description>
    427         </bitlbee-setting>
    428 
    429         <bitlbee-setting name="auto_reconnect" type="boolean">
    430                 <default>False</default>
    431 
    432                 <description>
    433                         <para>
    434                                 If an IM-connections breaks, you're supposed to bring it back up yourself. Having BitlBee do this automatically might not always be a good idea, for several reasons. If you want the connections to be restored automatically, you can enable this setting.
    435                         </para>
    436 
    437                         <para>
    438                                 See also the <emphasis>auto_reconnect_delay</emphasis> setting.
    439                         </para>
    440                 </description>
    441 
    442         </bitlbee-setting>
    443 
    444         <bitlbee-setting name="auto_reconnect_delay" type="integer">
    445                 <default>300</default>
    446 
    447                 <description>
    448 
    449                         <para>
    450                                 Tell BitlBee after how many seconds it should attempt to bring an IM-connection back up after a crash. It's not a good idea to set this value very low, it will cause too much useless traffic when an IM-server is down for a few hours.
    451                         </para>
    452 
    453                         <para>
    454                                 See also the <emphasis>auto_reconnect</emphasis> setting.
    455                         </para>
    456                 </description>
    457         </bitlbee-setting>
    458 
    459         <bitlbee-setting name="buddy_sendbuffer" type="boolean">
    460                 <default>False</default>
    461 
    462                 <description>
    463 
    464                         <para>
    465                                 By default, when you send a message to someone, BitlBee forwards this message to the user immediately. When you paste a large number of lines, the lines will be sent in separate messages, which might not be very nice to read. If you enable this setting, BitlBee will buffer your messages and wait for more data.
    466                         </para>
    467 
    468                         <para>
    469                                 Using the <emphasis>buddy_sendbuffer_delay</emphasis> setting you can specify the number of seconds BitlBee should wait for more data before the complete message is sent.
    470                         </para>
    471 
    472                         <para>
    473                                 Please note that if you remove a buddy from your list (or if the connection to that user drops) and there's still data in the buffer, this data will be lost. BitlBee will not try to send the message to the user in those cases.
    474                         </para>
    475                 </description>
    476 
    477         </bitlbee-setting>
    478 
    479         <bitlbee-setting name="buddy_sendbuffer_delay" type="integer">
    480                 <default>200</default>
    481 
    482                 <description>
    483 
    484                         <para>
    485                                 Tell BitlBee after how many (mili)seconds a buffered message should be sent. Values greater than 5 will be interpreted as miliseconds, 5 and lower as seconds.
    486                         </para>
    487 
    488                         <para>
    489                                 See also the <emphasis>buddy_sendbuffer</emphasis> setting.
    490                         </para>
    491                 </description>
    492 
    493         </bitlbee-setting>
    494 
    495         <bitlbee-setting name="default_target" type="string">
    496                 <default>root</default>
    497                 <possible-values>root, last</possible-values>
    498 
    499                 <description>
    500                         <para>
    501                                 With this value set to <emphasis>root</emphasis>, lines written in the control channel without any nickname in front of them will be interpreted as commands. If you want BitlBee to send those lines to the last person you addressed in the control channel, set this to <emphasis>last</emphasis>.
    502                         </para>
    503                 </description>
    504 
    505         </bitlbee-setting>
    506 
    507         <bitlbee-setting name="display_namechanges" type="boolean">
    508                 <default>False</default>
    509 
    510                 <para>
    511                         With this option enabled, root will inform you when someone in your buddy list changes his/her "friendly name".
    512                 </para>
    513         </bitlbee-setting>
    514 
    515         <bitlbee-setting name="password" type="string">
    516                 <description>
    517                         <para>
    518                                 Use this setting to change your "NickServ" password.
    519                         </para>
    520                 </description>
    521         </bitlbee-setting>
    522 
    523         <bitlbee-setting name="query_order" type="string">
     469        <bitlbee-setting name="lcnicks" type="boolean" scope="global">
     470                <default>true</default>
     471
     472                <description>
     473                        <para>
     474                                Hereby you can change whether you want all lower case nick names or leave the case as it intended by your peer.
     475                        </para>
     476                </description>
     477
     478        </bitlbee-setting>
     479
     480        <bitlbee-setting name="ops" type="string" scope="global">
     481                <default>both</default>
     482                <possible-values>both, root, user, none</possible-values>
     483
     484                <description>
     485                        <para>
     486                                Some people prefer themself and root to have operator status in &amp;bitlbee, other people don't. You can change these states using this setting.
     487                        </para>
     488
     489                        <para>
     490                                The value "both" means both user and root get ops. "root" means, well, just root. "user" means just the user. "none" means nobody will get operator status.
     491                        </para>
     492                </description>
     493        </bitlbee-setting>
     494
     495        <bitlbee-setting name="password" type="string" scope="both">
     496                <description>
     497                        <para>
     498                                Use this global setting to change your "NickServ" password.
     499                        </para>
     500                       
     501                        <para>
     502                                This setting is also available for all IM accounts to change the password BitlBee uses to connect to the service.
     503                        </para>
     504                       
     505                        <para>
     506                                Note that BitlBee will always say this setting is empty. This doesn't mean there is no password, it just means that, for security reasons, BitlBee stores passwords somewhere else so they can't just be retrieved in plain text.
     507                        </para>
     508                </description>
     509        </bitlbee-setting>
     510       
     511        <bitlbee-setting name="port" type="integer" scope="account">
     512                <description>
     513                        <para>
     514                                Currently only available for Jabber connections. Specifies the port number to connect to. Usually this should be set to 5222, or 5223 for SSL-connections.
     515                        </para>
     516                </description>
     517        </bitlbee-setting>
     518
     519        <bitlbee-setting name="private" type="boolean" scope="global">
     520                <default>true</default>
     521
     522                <description>
     523                        <para>
     524                                If value is true, messages from users will appear in separate query windows. If false, messages from users will appear in the control channel.
     525                        </para>
     526
     527                        <para>
     528                                This setting is remembered (during one session) per-user, this setting only changes the default state. This option takes effect as soon as you reconnect.
     529                        </para>
     530                </description>
     531        </bitlbee-setting>
     532
     533        <bitlbee-setting name="query_order" type="string" scope="global">
    524534                <default>lifo</default>
    525535                <possible-values>lifo, fifo</possible-values>
     
    536546        </bitlbee-setting>
    537547
    538         <bitlbee-setting name="lcnicks" type="boolean">
    539                 <default>True</default>
    540 
    541                 <description>
    542                         <para>
    543                                 Hereby you can change whether you want all lower case nick names or leave the case as it intended by your peer.
    544                         </para>
    545                 </description>
    546 
     548        <bitlbee-setting name="resource" type="string" scope="account">
     549                <default>BitlBee</default>
     550
     551                <description>
     552                        <para>
     553                                Can be set for Jabber connections. You can use this to connect to your Jabber account from multiple clients at once, with every client using a different resource string.
     554                        </para>
     555                </description>
     556        </bitlbee-setting>
     557
     558        <bitlbee-setting name="save_on_quit" type="boolean" scope="global">
     559                <default>true</default>
     560
     561                <description>
     562                        <para>
     563                                If enabled causes BitlBee to save all current settings and account details when user disconnects. This is enabled by default, and these days there's not really a reason to have it disabled anymore.
     564                        </para>
     565                </description>
     566        </bitlbee-setting>
     567
     568        <bitlbee-setting name="server" type="string" scope="account">
     569                <description>
     570                        <para>
     571                                Can be set for Jabber- and OSCAR-connections. For OSCAR, this must be set to <emphasis>login.icq.com</emphasis> if it's an ICQ connection, or <emphasis>login.oscar.aol.com</emphasis> if it's an AIM connection. For Jabber, you have to set this if the servername isn't equal to the part after the @ in the Jabber handle.
     572                        </para>
     573                </description>
     574        </bitlbee-setting>
     575
     576        <bitlbee-setting name="ssl" type="boolean" scope="account">
     577                <default>false</default>
     578
     579                <description>
     580                        <para>
     581                                Currently only available for Jabber connections. Set this to true if the server accepts SSL connections.
     582                        </para>
     583                </description>
     584        </bitlbee-setting>
     585
     586        <bitlbee-setting name="strip_html" type="boolean" scope="global">
     587                <default>true</default>
     588
     589                <description>
     590                        <para>
     591                                Determines what BitlBee should do with HTML in messages. Normally this is turned on and HTML will be stripped from messages, if BitlBee thinks there is HTML.
     592                        </para>
     593                        <para>
     594                                If BitlBee fails to detect this sometimes (most likely in AIM messages over an ICQ connection), you can set this setting to <emphasis>always</emphasis>, but this might sometimes accidentally strip non-HTML things too.
     595                        </para>
     596                </description>
     597        </bitlbee-setting>
     598
     599        <bitlbee-setting name="to_char" type="string" scope="global">
     600                <default>": "</default>
     601
     602                <description>
     603                        <para>
     604                                It's customary that messages meant for one specific person on an IRC channel are prepended by his/her alias followed by a colon ':'. BitlBee does this by default. If you prefer a different character, you can set it using <emphasis>set to_char</emphasis>.
     605                        </para>
     606
     607                        <para>
     608                                Please note that this setting is only used for incoming messages. For outgoing messages you can use ':' (colon) or ',' to separate the destination nick from the message, and this is not configurable.
     609                        </para>
     610                </description>
     611        </bitlbee-setting>
     612
     613        <bitlbee-setting name="typing_notice" type="boolean" scope="global">
     614                <default>false</default>
     615
     616                <description>
     617                        <para>
     618                                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. ;-)
     619                        </para>
     620                </description>
     621        </bitlbee-setting>
     622
     623        <bitlbee-setting name="web_aware" type="string" scope="account">
     624                <default>false</default>
     625
     626                <description>
     627                        <para>
     628                                ICQ allows people to see if you're on-line via a CGI-script. (http://status.icq.com/online.gif?icq=UIN) This can be nice to put on your website, but it seems that spammers also use it to see if you're online without having to add you to their contact list. So to prevent ICQ spamming, recent versions of BitlBee disable this feature by default.
     629                        </para>
     630
     631                        <para>
     632                                Unless you really intend to use this feature somewhere (on forums or maybe a website), it's probably better to keep this setting disabled.
     633                        </para>
     634                </description>
    547635        </bitlbee-setting>
    548636
     
    674762                                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.
    675763                        </para>
     764
     765                        <para>
     766                                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.
     767                        </para>
    676768                </description>
    677769
  • doc/user-guide/help.xsl

    rf4aa393 rd8d63a2  
    77        version="1.1">
    88
    9         <xsl:output method="text" encoding="iso-8859-1" standalone="yes"/>
     9        <xsl:output method="text" encoding="utf-8" standalone="yes"/>
    1010        <xsl:strip-space elements="*"/>
    1111
     
    5858                        <xsl:text>?set </xsl:text><xsl:value-of select="@name"/><xsl:text>&#10;</xsl:text>
    5959                        <xsl:text>_b_Type:_b_ </xsl:text><xsl:value-of select="@type"/><xsl:text>&#10;</xsl:text>
    60                         <xsl:text>_b_Default:_b_ </xsl:text><xsl:value-of select="default"/><xsl:text>&#10;</xsl:text>
     60                        <xsl:text>_b_Scope:_b_ </xsl:text><xsl:value-of select="@scope"/><xsl:text>&#10;</xsl:text>
     61                        <xsl:if test="default">
     62                                <xsl:text>_b_Default:_b_ </xsl:text><xsl:value-of select="default"/><xsl:text>&#10;</xsl:text>
     63                        </xsl:if>
    6164                        <xsl:if test="possible-values">
    6265                                <xsl:text>_b_Possible Values:_b_ </xsl:text><xsl:value-of select="possible-values"/><xsl:text>&#10;</xsl:text>
  • ipc.c

    rf4aa393 rd8d63a2  
    9999        { "die",        0, ipc_master_cmd_die,        0 },
    100100        { "wallops",    1, NULL,                      IPC_CMD_TO_CHILDREN },
    101         { "lilo",       1, NULL,                      IPC_CMD_TO_CHILDREN },
     101        { "wall",       1, NULL,                      IPC_CMD_TO_CHILDREN },
    102102        { "opermsg",    1, NULL,                      IPC_CMD_TO_CHILDREN },
    103103        { "rehash",     0, ipc_master_cmd_rehash,     0 },
     
    122122}
    123123
    124 static void ipc_child_cmd_lilo( irc_t *irc, char **cmd )
     124static void ipc_child_cmd_wall( irc_t *irc, char **cmd )
    125125{
    126126        if( !( irc->status & USTATUS_LOGGED_IN ) )
     
    175175        { "die",        0, ipc_child_cmd_die,         0 },
    176176        { "wallops",    1, ipc_child_cmd_wallops,     0 },
    177         { "lilo",       1, ipc_child_cmd_lilo,        0 },
     177        { "wall",       1, ipc_child_cmd_wall,        0 },
    178178        { "opermsg",    1, ipc_child_cmd_opermsg,     0 },
    179179        { "rehash",     0, ipc_child_cmd_rehash,      0 },
  • irc.c

    rf4aa393 rd8d63a2  
    3333GSList *irc_connection_list = NULL;
    3434
    35 static char *passchange (irc_t *irc, void *set, char *value)
    36 {
    37         irc_setpass (irc, value);
    38         return (NULL);
     35static char *passchange( set_t *set, char *value )
     36{
     37        irc_t *irc = set->data;
     38       
     39        irc_setpass( irc, value );
     40        irc_usermsg( irc, "Password successfully changed" );
     41        return NULL;
    3942}
    4043
     
    4649        char buf[128];
    4750#ifdef IPV6
    48         struct sockaddr_in6 sock[1];
    49 #else
     51        struct sockaddr_in6 sock6[1];
     52        unsigned int i6;
     53#endif
    5054        struct sockaddr_in sock[1];
    51 #endif
    5255       
    5356        irc = g_new0( irc_t, 1 );
     
    6972       
    7073        i = sizeof( *sock );
     74#ifdef IPV6
     75        i6 = sizeof( *sock6 );
     76#endif
    7177       
    7278        if( global.conf->hostname )
    7379                irc->myhost = g_strdup( global.conf->hostname );
    7480#ifdef IPV6
    75         else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx )
    76         {
    77                 if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) )
     81        else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
     82        {
     83                if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
    7884                        irc->myhost = g_strdup( peer->h_name );
    79                 else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
     85                else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
    8086                        irc->myhost = g_strdup( ipv6_unwrap( buf ) );
    8187        }
    82 #else
    83         else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx )
    84         {
    85                 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) )
     88#endif
     89        else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
     90        {
     91                if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
    8692                        irc->myhost = g_strdup( peer->h_name );
    87                 else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
     93                else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
    8894                        irc->myhost = g_strdup( buf );
    8995        }
    90 #endif
    9196       
    9297        i = sizeof( *sock );
    9398#ifdef IPV6
    94         if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx )
    95         {
    96                 if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) )
     99        i6 = sizeof( *sock6 );
     100        if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
     101        {
     102                if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
    97103                        irc->host = g_strdup( peer->h_name );
    98                 else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
     104                else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
    99105                        irc->host = g_strdup( ipv6_unwrap( buf ) );
    100106        }
    101 #else
    102         if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx )
    103         {
    104                 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) )
     107        else
     108#endif
     109        if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
     110        {
     111                if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
    105112                        irc->host = g_strdup( peer->h_name );
    106                 else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
     113                else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
    107114                        irc->host = g_strdup( buf );
    108115        }
    109 #endif
    110116       
    111117        /* Rare, but possible. */
     
    120126        irc_connection_list = g_slist_append( irc_connection_list, irc );
    121127       
    122         set_add( irc, "away_devoice", "true",  set_eval_away_devoice );
    123         set_add( irc, "auto_connect", "true", set_eval_bool );
    124         set_add( irc, "auto_reconnect", "false", set_eval_bool );
    125         set_add( irc, "auto_reconnect_delay", "300", set_eval_int );
    126         set_add( irc, "buddy_sendbuffer", "false", set_eval_bool );
    127         set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int );
    128         set_add( irc, "charset", "iso8859-1", set_eval_charset );
    129         set_add( irc, "debug", "false", set_eval_bool );
    130         set_add( irc, "default_target", "root", NULL );
    131         set_add( irc, "display_namechanges", "false", set_eval_bool );
    132         set_add( irc, "handle_unknown", "root", NULL );
    133         set_add( irc, "lcnicks", "true", set_eval_bool );
    134         set_add( irc, "ops", "both", set_eval_ops );
    135         set_add( irc, "private", "true", set_eval_bool );
    136         set_add( irc, "query_order", "lifo", NULL );
    137         set_add( irc, "save_on_quit", "true", set_eval_bool );
    138         set_add( irc, "strip_html", "true", NULL );
    139         set_add( irc, "to_char", ": ", set_eval_to_char );
    140         set_add( irc, "typing_notice", "false", set_eval_bool );
    141         set_add( irc, "password", NULL, passchange);
     128        set_add( &irc->set, "away_devoice", "true",  set_eval_away_devoice, irc );
     129        set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
     130        set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc );
     131        set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc );
     132        set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );
     133        set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );
     134        set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc );
     135        set_add( &irc->set, "debug", "false", set_eval_bool, irc );
     136        set_add( &irc->set, "default_target", "root", NULL, irc );
     137        set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc );
     138        set_add( &irc->set, "handle_unknown", "root", NULL, irc );
     139        set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc );
     140        set_add( &irc->set, "ops", "both", set_eval_ops, irc );
     141        set_add( &irc->set, "password", NULL, passchange, irc );
     142        set_add( &irc->set, "private", "true", set_eval_bool, irc );
     143        set_add( &irc->set, "query_order", "lifo", NULL, irc );
     144        set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
     145        set_add( &irc->set, "strip_html", "true", NULL, irc );
     146        set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
     147        set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
    142148       
    143149        conf_loaddefaults( irc );
     
    203209void irc_free(irc_t * irc)
    204210{
    205         account_t *account, *accounttmp;
     211        account_t *account;
    206212        user_t *user, *usertmp;
    207         nick_t *nick, *nicktmp;
    208213        help_t *helpnode, *helpnodetmp;
    209         set_t *setnode, *setnodetmp;
    210214       
    211215        log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
    212216       
    213         if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) )
     217        if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) )
    214218                if( storage_save( irc, TRUE ) != STORAGE_OK )
    215219                        irc_usermsg( irc, "Error while saving settings!" );
     
    251255                query_del(irc, irc->queries);
    252256       
    253         if (irc->accounts != NULL) {
    254                 account = irc->accounts;
    255                 while (account != NULL) {
    256                         g_free(account->user);
    257                         g_free(account->pass);
    258                         g_free(account->server);
    259                         accounttmp = account;
    260                         account = account->next;
    261                         g_free(accounttmp);
    262                 }
    263         }
     257        while (irc->accounts)
     258                account_del(irc, irc->accounts);
     259       
     260        while (irc->set)
     261                set_del(&irc->set, irc->set->key);
    264262       
    265263        if (irc->users != NULL) {
     
    286284        g_hash_table_destroy(irc->watches);
    287285       
    288         if (irc->nicks != NULL) {
    289                 nick = irc->nicks;
    290                 while (nick != NULL) {
    291                         g_free(nick->nick);
    292                         g_free(nick->handle);
    293                                        
    294                         nicktmp = nick;
    295                         nick = nick->next;
    296                         g_free(nicktmp);
    297                 }
    298         }
    299286        if (irc->help != NULL) {
    300287                helpnode = irc->help;
     
    307294                }
    308295        }
    309         if (irc->set != NULL) {
    310                 setnode = irc->set;
    311                 while (setnode != NULL) {
    312                         g_free(setnode->key);
    313                         g_free(setnode->def);
    314                         g_free(setnode->value);
    315                        
    316                         setnodetmp = setnode;
    317                         setnode = setnode->next;
    318                         g_free(setnodetmp);
    319                 }
    320         }
    321296        g_free(irc);
    322297       
     
    329304void irc_setpass (irc_t *irc, const char *pass)
    330305{
    331         if (irc->password) g_free (irc->password);
     306        g_free (irc->password);
    332307       
    333308        if (pass) {
    334309                irc->password = g_strdup (pass);
    335                 irc_usermsg (irc, "Password successfully changed");
    336310        } else {
    337311                irc->password = NULL;
     
    364338                        }
    365339                       
    366                         if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
     340                        if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
    367341                        {
    368342                                conv[IRC_MAX_LINE] = 0;
     
    584558       
    585559        strip_newlines( line );
    586         if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
     560        if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
    587561        {
    588562                char conv[IRC_MAX_LINE+1];
     
    611585                   the queue. If it's FALSE, we emptied the buffer and saved ourselves some work
    612586                   in the event queue. */
    613                 if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) )
    614                         irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc );
     587                /* Really can't be done as long as the code doesn't do error checking very well:
     588                if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) */
     589               
     590                /* So just always do it via the event handler. */
     591                irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc );
    615592        }
    616593       
     
    652629        char namelist[385] = "";
    653630        struct conversation *c = NULL;
     631        char *ops = set_getstr( &irc->set, "ops" );
    654632       
    655633        /* RFCs say there is no error reply allowed on NAMES, so when the
     
    666644                        }
    667645                       
    668                         if( u->gc && !u->away && set_getint( irc, "away_devoice" ) )
     646                        if( u->gc && !u->away && set_getbool( &irc->set, "away_devoice" ) )
    669647                                strcat( namelist, "+" );
     648                        else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ||
     649                                 ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) )
     650                                strcat( namelist, "@" );
    670651                       
    671652                        strcat( namelist, u->nick );
     
    676657        {
    677658                GList *l;
    678                 char *ops = set_getstr( irc, "ops" );
    679659               
    680660                /* root and the user aren't in the channel userlist but should
     
    924904{
    925905        char *nick, *s;
    926         char reason[64];
     906        char reason[128];
    927907       
    928908        if( u->gc && u->gc->flags & OPT_LOGGING_OUT )
    929909        {
    930                 if( u->gc->user->proto_opt[0][0] )
     910                if( u->gc->acc->server )
    931911                        g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
    932                                     u->gc->user->proto_opt[0] );
     912                                    u->gc->acc->server );
    933913                else if( ( s = strchr( u->gc->username, '@' ) ) )
    934914                        g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
     
    936916                else
    937917                        g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
    938                                     u->gc->prpl->name, irc->myhost );
     918                                    u->gc->acc->prpl->name, irc->myhost );
    939919               
    940920                /* proto_opt might contain garbage after the : */
     
    1012992                else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
    1013993                {
    1014                         if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 )
     994                        if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 )
    1015995                        {
    1016996                                time_t current_typing_notice = time( NULL );
     
    1018998                                if( current_typing_notice - u->last_typing_notice >= 5 )
    1019999                                {
    1020                                         u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
     1000                                        u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
    10211001                                        u->last_typing_notice = current_typing_notice;
    10221002                                }
     
    10511031                }
    10521032        }
    1053         else if( c && c->gc && c->gc->prpl )
     1033        else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
    10541034        {
    10551035                return( bim_chat_msg( c->gc, c->id, s ) );
     
    10831063        if( !u || !u->gc ) return;
    10841064       
    1085         if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
     1065        if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
    10861066        {
    10871067                int delay;
     
    11101090                strcat( u->sendbuf, "\n" );
    11111091               
    1112                 delay = set_getint( irc, "buddy_sendbuffer_delay" );
     1092                delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
    11131093                if( delay <= 5 )
    11141094                        delay *= 1000;
     
    11751155                int len = strlen( irc->nick) + 3;
    11761156                prefix = g_new (char, len );
    1177                 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );
     1157                g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
    11781158                prefix[len-1] = 0;
    11791159        }
  • irc.h

    rf4aa393 rd8d63a2  
    9898
    9999#include "user.h"
    100 #include "nick.h"
     100// #include "nick.h"
    101101
    102102extern GSList *irc_connection_list;
  • irc_commands.c

    rf4aa393 rd8d63a2  
    150150                irc_part( irc, u, c->channel );
    151151               
    152                 if( c->gc && c->gc->prpl )
     152                if( c->gc )
    153153                {
    154154                        c->joined = 0;
    155                         c->gc->prpl->chat_leave( c->gc, c->id );
     155                        c->gc->acc->prpl->chat_leave( c->gc, c->id );
    156156                }
    157157        }
     
    173173                        user_t *u = user_find( irc, cmd[1] + 1 );
    174174                       
    175                         if( u && u->gc && u->gc->prpl && u->gc->prpl->chat_open )
     175                        if( u && u->gc && u->gc->acc->prpl->chat_open )
    176176                        {
    177177                                irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] );
    178178                               
    179                                 if( !u->gc->prpl->chat_open( u->gc, u->handle ) )
     179                                if( !u->gc->acc->prpl->chat_open( u->gc, u->handle ) )
    180180                                {
    181181                                        irc_usermsg( irc, "Could not open a groupchat with %s.", u->nick );
     
    205205       
    206206        if( u && c && ( u->gc == c->gc ) )
    207                 if( c->gc && c->gc->prpl && c->gc->prpl->chat_invite )
    208                 {
    209                         c->gc->prpl->chat_invite( c->gc, c->id, "", u->handle );
     207                if( c->gc && c->gc->acc->prpl->chat_invite )
     208                {
     209                        c->gc->acc->prpl->chat_invite( c->gc, c->id, "", u->handle );
    210210                        irc_reply( irc, 341, "%s %s", nick, channel );
    211211                        return;
     
    230230                {
    231231                        unsigned int i;
    232                         char *t = set_getstr( irc, "default_target" );
     232                        char *t = set_getstr( &irc->set, "default_target" );
    233233                       
    234234                        if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
     
    477477               
    478478                if( u->gc )
    479                         irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username,
    480                                    *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name );
     479                        irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->acc->user,
     480                                   u->gc->acc->server && *u->gc->acc->server ? u->gc->acc->server : "",
     481                                   u->gc->acc->prpl->name );
    481482                else
    482483                        irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
     
    592593        { "die",         0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    593594        { "wallops",     1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    594         { "lilo",        1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
     595        { "wall",        1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    595596        { "rehash",      0, irc_cmd_rehash,      IRC_CMD_OPER_ONLY },
    596597        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
  • lib/events.h

    rf4aa393 rd8d63a2  
    2020 */
    2121
    22 /*
    23  * Split off the event handling things from proxy.[ch] (and adding timer
    24  * stuff. This to allow BitlBee to use other libs than GLib for event
    25  * handling.
    26  */
     22/* This stuff used to be in proxy.c too, but I split it off so BitlBee can
     23   use other libraries (like libevent) to handle events. proxy.c is one very
     24   nice piece of work from Gaim. It connects to a TCP server in the back-
     25   ground and calls a callback function once the connection is ready to use.
     26   This function (proxy_connect()) can be found in proxy.c. (It also
     27   transparently handles HTTP/SOCKS proxies, when necessary.)
     28   
     29   This file offers some extra event handling toys, which will be handled
     30   by GLib or libevent. The advantage of using libevent is that it can use
     31   more advanced I/O polling functions like epoll() in recent Linux
     32   kernels. This should improve BitlBee's scalability. */
    2733
    2834
     
    3945#include <gmodule.h>
    4046
     47/* The conditions you can pass to gaim_input_add()/that will be passed to
     48   the given callback function. */
    4149typedef enum {
    4250        GAIM_INPUT_READ = 1 << 1,
     
    4553typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond);
    4654
     55/* For internal use. */
    4756#define GAIM_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)
    4857#define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
     
    5261#define event_debug( x... )
    5362
     63/* Call this once when the program starts. It'll initialize the event handler
     64   library (if necessary) and then return immediately. */
    5465G_MODULE_EXPORT void b_main_init();
     66
     67/* This one enters the event loop. It shouldn't return until one of the event
     68   handlers calls b_main_quit(). */
    5569G_MODULE_EXPORT void b_main_run();
    5670G_MODULE_EXPORT void b_main_quit();
    5771
     72
     73/* Add event handlers (for I/O or a timeout). The event handler will be called
     74   every time the event "happens", until your event handler returns FALSE (or
     75   until you remove it using b_event_remove(). As usual, the data argument
     76   can be used to pass your own data to the event handler. */
    5877G_MODULE_EXPORT gint b_input_add(int fd, b_input_condition cond, b_event_handler func, gpointer data);
    5978G_MODULE_EXPORT gint b_timeout_add(gint timeout, b_event_handler func, gpointer data);
    6079G_MODULE_EXPORT void b_event_remove(gint id);
    6180
     81/* For now, closesocket() is only a function when using libevent. With GLib
     82   it's a preprocessor macro. */
    6283#ifdef EVENTS_LIBEVENT
    6384G_MODULE_EXPORT void closesocket(int fd);
  • lib/events_glib.c

    rf4aa393 rd8d63a2  
    122122gint b_timeout_add(gint timeout, b_event_handler func, gpointer data)
    123123{
    124         gint st = g_timeout_add(timeout, func, data);
     124        /* GSourceFunc and the BitlBee event handler function aren't
     125           really the same, but they're "compatible". ;-) It will do
     126           for now, BitlBee only looks at the "data" argument. */
     127        gint st = g_timeout_add(timeout, (GSourceFunc) func, data);
    125128       
    126129        event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st );
  • lib/events_libevent.c

    rf4aa393 rd8d63a2  
    101101       
    102102        /* Since the called function might cancel this handler already
    103            (which free()s b_ev, we have to remember the ID here. */
     103           (which free()s b_ev), we have to remember the ID here. */
    104104        id = b_ev->id;
    105105       
  • lib/misc.c

    rf4aa393 rd8d63a2  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    1111 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
    1212 *                          (and possibly other members of the Gaim team)
    13  * Copyright 2002-2005 Wilmer van der Gaast <wilmer@gaast.net>
     13 * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net>
    1414 */
    1515
     
    5454}
    5555
    56 char *add_cr(char *text)
    57 {
    58         char *ret = NULL;
    59         int count = 0, j;
    60         unsigned int i;
    61 
    62         if (text[0] == '\n')
    63                 count++;
    64         for (i = 1; i < strlen(text); i++)
    65                 if (text[i] == '\n' && text[i - 1] != '\r')
    66                         count++;
    67 
    68         if (count == 0)
    69                 return g_strdup(text);
    70 
    71         ret = g_malloc0(strlen(text) + count + 1);
    72 
    73         i = 0; j = 0;
    74         if (text[i] == '\n')
    75                 ret[j++] = '\r';
    76         ret[j++] = text[i++];
    77         for (; i < strlen(text); i++) {
    78                 if (text[i] == '\n' && text[i - 1] != '\r')
    79                         ret[j++] = '\r';
    80                 ret[j++] = text[i];
    81         }
    82 
    83         return ret;
    84 }
    85 
    86 static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";
    87 
    88 /* XXX Find bug */
    89 char *tobase64(const char *text)
    90 {
    91         char *out = NULL;
    92         const char *c;
    93         unsigned int tmp = 0;
    94         int len = 0, n = 0;
    95 
    96         c = text;
    97 
    98         while (*c) {
    99                 tmp = tmp << 8;
    100                 tmp += *c;
    101                 n++;
    102 
    103                 if (n == 3) {
    104                         out = g_realloc(out, len + 4);
    105                         out[len] = alphabet[(tmp >> 18) & 0x3f];
    106                         out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
    107                         out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
    108                         out[len + 3] = alphabet[tmp & 0x3f];
    109                         len += 4;
    110                         tmp = 0;
    111                         n = 0;
    112                 }
    113                 c++;
    114         }
    115         switch (n) {
    116 
    117         case 2:
    118                 tmp <<= 8;
    119                 out = g_realloc(out, len + 5);
    120                 out[len] = alphabet[(tmp >> 18) & 0x3f];
    121                 out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
    122                 out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
    123                 out[len + 3] = '=';
    124                 out[len + 4] = 0;
    125                 break;
    126         case 1:
    127                 tmp <<= 16;
    128                 out = g_realloc(out, len + 5);
    129                 out[len] = alphabet[(tmp >> 18) & 0x3f];
    130                 out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
    131                 out[len + 2] = '=';
    132                 out[len + 3] = '=';
    133                 out[len + 4] = 0;
    134                 break;
    135         case 0:
    136                 out = g_realloc(out, len + 1);
    137                 out[len] = 0;
    138                 break;
    139         }
    140         return out;
    141 }
    142 
    14356char *normalize(const char *s)
    14457{
     
    18194typedef struct htmlentity
    18295{
    183         char code[8];
    184         char is[4];
     96        char code[7];
     97        char is[3];
    18598} htmlentity_t;
    186 
    187 /* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */
    18899
    189100static const htmlentity_t ent[] =
     
    479390}
    480391
    481 char *set_eval_charset( irc_t *irc, set_t *set, char *value )
    482 {
    483         GIConv cd;
    484 
    485         if ( g_strncasecmp( value, "none", 4 ) == 0 )
    486                 return( value );
    487 
    488         cd = g_iconv_open( "UTF-8", value );
    489         if( cd == (GIConv) -1 )
    490                 return( NULL );
    491 
    492         g_iconv_close( cd );
    493         return( value );
    494 }
     392/* A pretty reliable random number generator. Tries to use the /dev/random
     393   devices first, and falls back to the random number generator from libc
     394   when it fails. Opens randomizer devices with O_NONBLOCK to make sure a
     395   lack of entropy won't halt BitlBee. */
     396void random_bytes( unsigned char *buf, int count )
     397{
     398        static int use_dev = -1;
     399       
     400        /* Actually this probing code isn't really necessary, is it? */
     401        if( use_dev == -1 )
     402        {
     403                if( access( "/dev/random", R_OK ) == 0 || access( "/dev/urandom", R_OK ) == 0 )
     404                        use_dev = 1;
     405                else
     406                {
     407                        use_dev = 0;
     408                        srand( ( getpid() << 16 ) ^ time( NULL ) );
     409                }
     410        }
     411       
     412        if( use_dev )
     413        {
     414                int fd;
     415               
     416                /* At least on Linux, /dev/random can block if there's not
     417                   enough entropy. We really don't want that, so if it can't
     418                   give anything, use /dev/urandom instead. */
     419                if( ( fd = open( "/dev/random", O_RDONLY | O_NONBLOCK ) ) >= 0 )
     420                        if( read( fd, buf, count ) == count )
     421                        {
     422                                close( fd );
     423                                return;
     424                        }
     425                close( fd );
     426               
     427                /* urandom isn't supposed to block at all, but just to be
     428                   sure. If it blocks, we'll disable use_dev and use the libc
     429                   randomizer instead. */
     430                if( ( fd = open( "/dev/urandom", O_RDONLY | O_NONBLOCK ) ) >= 0 )
     431                        if( read( fd, buf, count ) == count )
     432                        {
     433                                close( fd );
     434                                return;
     435                        }
     436                close( fd );
     437               
     438                /* If /dev/random blocks once, we'll still try to use it
     439                   again next time. If /dev/urandom also fails for some
     440                   reason, stick with libc during this session. */
     441               
     442                use_dev = 0;
     443                srand( ( getpid() << 16 ) ^ time( NULL ) );
     444        }
     445       
     446        if( !use_dev )
     447        {
     448                int i;
     449               
     450                /* Possibly the LSB of rand() isn't very random on some
     451                   platforms. Seems okay on at least Linux and OSX though. */
     452                for( i = 0; i < count; i ++ )
     453                        buf[i] = rand() & 0xff;
     454        }
     455}
     456
     457int is_bool( char *value )
     458{
     459        if( *value == 0 )
     460                return 0;
     461       
     462        if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
     463                return 1;
     464        if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
     465                return 1;
     466       
     467        while( *value )
     468                if( !isdigit( *value ) )
     469                        return 0;
     470                else
     471                        value ++;
     472       
     473        return 1;
     474}
     475
     476int bool2int( char *value )
     477{
     478        int i;
     479       
     480        if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
     481                return 1;
     482        if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
     483                return 0;
     484       
     485        if( sscanf( value, "%d", &i ) == 1 )
     486                return i;
     487       
     488        return 0;
     489}
  • lib/misc.h

    rf4aa393 rd8d63a2  
    2424*/
    2525
    26 #ifndef _UTIL_H
    27 #define _UTIL_H
     26#ifndef _MISC_H
     27#define _MISC_H
     28
     29#include <gmodule.h>
     30#include <time.h>
    2831
    2932G_MODULE_EXPORT void strip_linefeed( gchar *text );
    3033G_MODULE_EXPORT char *add_cr( char *text );
    3134G_MODULE_EXPORT char *strip_newlines(char *source);
    32 G_MODULE_EXPORT char *tobase64( const char *text );
    3335G_MODULE_EXPORT char *normalize( const char *s );
    3436G_MODULE_EXPORT void info_string_append( GString *str, char *newline, char *name, char *value );
     
    4648
    4749G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
    48 char *set_eval_charset( irc_t *irc, set_t *set, char *value );
     50
     51G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count );
     52
     53G_MODULE_EXPORT int is_bool( char *value );
     54G_MODULE_EXPORT int bool2int( char *value );
    4955
    5056#endif
  • lib/proxy.c

    rf4aa393 rd8d63a2  
    4141#include "nogaim.h"
    4242#include "proxy.h"
     43#include "base64.h"
    4344
    4445char proxyhost[128] = "";
  • lib/ssl_client.h

    rf4aa393 rd8d63a2  
    2424*/
    2525
     26/* ssl_client makes it easier to open SSL connections to servers. (It
     27   doesn't offer SSL server functionality yet, but it could be useful
     28   to add it later.) Different ssl_client modules are available, and
     29   ssl_client tries to make them all behave the same. It's very simple
     30   and basic, it just imitates the proxy_connect() function from the
     31   Gaim libs and passes the socket to the program once the handshake
     32   is completed. */
     33
    2634#include <glib.h>
    2735#include "proxy.h"
    2836
     37/* Some generic error codes. Especially SSL_AGAIN is important if you
     38   want to do asynchronous I/O. */
    2939#define SSL_OK            0
    3040#define SSL_NOHANDSHAKE   1
     
    3343extern int ssl_errno;
    3444
     45/* This is what your callback function should look like. */
    3546typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);
    3647
     48
     49/* Connect to host:port, call the given function when the connection is
     50   ready to be used for SSL traffic. This is all done asynchronously, no
     51   blocking I/O! (Except for the DNS lookups, for now...) */
    3752G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data );
     53
     54/* Obviously you need special read/write functions to read data. */
    3855G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );
    3956G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
     57
     58/* Abort the SSL connection and disconnect the socket. Do not use close()
     59   directly, both the SSL library and the peer will be unhappy! */
    4060G_MODULE_EXPORT void ssl_disconnect( void *conn_ );
     61
     62/* Get the fd for this connection, you will usually need it for event
     63   handling. */
    4164G_MODULE_EXPORT int ssl_getfd( void *conn );
     65
     66/* This function returns GAIM_INPUT_READ/WRITE. With SSL connections it's
     67   possible that something has to be read while actually were trying to
     68   write something (think about key exchange/refresh/etc). So when an
     69   SSL operation returned SSL_AGAIN, *always* use this function when
     70   adding an event handler to the queue. (And it should perform exactly
     71   the same action as the handler that just received the SSL_AGAIN.) */
    4272G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
  • nick.c

    rf4aa393 rd8d63a2  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2727#include "bitlbee.h"
    2828
    29 void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick )
    30 {
    31         nick_t *m = NULL, *n = irc->nicks;
    32        
    33         while( n )
    34         {
    35                 if( ( g_strcasecmp( n->handle, handle ) == 0 ) && n->proto == proto )
    36                 {
    37                         g_free( n->nick );
    38                         n->nick = nick_dup( nick );
    39                         nick_strip( n->nick );
    40                        
    41                         return;
    42                 }
    43                 n = ( m = n )->next;    // :-P
    44         }
    45        
    46         if( m )
    47                 n = m->next = g_new0( nick_t, 1 );
     29/* Store handles in lower case and strip spaces, because AIM is braindead. */
     30static char *clean_handle( const char *orig )
     31{
     32        char *new = g_malloc( strlen( orig ) + 1 );
     33        int i = 0;
     34       
     35        do {
     36                if (*orig != ' ')
     37                        new[i++] = tolower( *orig );
     38        }
     39        while (*(orig++));
     40       
     41        return new;
     42}
     43
     44void nick_set( account_t *acc, const char *handle, const char *nick )
     45{
     46        char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 );
     47       
     48        store_handle = clean_handle( handle );
     49        strncpy( store_nick, nick, MAX_NICK_LENGTH );
     50        nick_strip( store_nick );
     51       
     52        g_hash_table_replace( acc->nicks, store_handle, store_nick );
     53}
     54
     55char *nick_get( account_t *acc, const char *handle, const char *realname )
     56{
     57        static char nick[MAX_NICK_LENGTH+1];
     58        char *store_handle, *found_nick;
     59        int inf_protection = 256;
     60       
     61        memset( nick, 0, MAX_NICK_LENGTH + 1 );
     62       
     63        store_handle = clean_handle( handle );
     64        /* Find out if we stored a nick for this person already. If not, try
     65           to generate a sane nick automatically. */
     66        if( ( found_nick = g_hash_table_lookup( acc->nicks, store_handle ) ) )
     67        {
     68                strncpy( nick, found_nick, MAX_NICK_LENGTH );
     69        }
    4870        else
    49                 n = irc->nicks = g_new0( nick_t, 1 );
    50        
    51         n->handle = g_strdup( handle );
    52         n->proto = proto;
    53         n->nick = nick_dup( nick );
    54        
    55         nick_strip( n->nick );
    56 }
    57 
    58 char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname )
    59 {
    60         static char nick[MAX_NICK_LENGTH+1];
    61         nick_t *n = irc->nicks;
    62         int inf_protection = 256;
    63        
    64         memset( nick, 0, MAX_NICK_LENGTH + 1 );
    65        
    66         while( n && !*nick )
    67                 if( ( n->proto == proto ) && ( g_strcasecmp( n->handle, handle ) == 0 ) )
    68                         strcpy( nick, n->nick );
    69                 else
    70                         n = n->next;
    71        
    72         if( !n )
    7371        {
    7472                char *s;
     
    8684               
    8785                nick_strip( nick );
    88                 if (set_getint(irc, "lcnicks"))
     86                if( set_getbool( &acc->irc->set, "lcnicks" ) )
    8987                        nick_lc( nick );
    9088        }
    91        
    92         while( !nick_ok( nick ) || user_find( irc, nick ) )
     89        g_free( store_handle );
     90       
     91        /* Now, find out if the nick is already in use at the moment, and make
     92           subtle changes to make it unique. */
     93        while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
    9394        {
    9495                if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
     
    106107                        int i;
    107108                       
    108                         irc_usermsg( irc, "WARNING: Almost had an infinite loop in nick_get()! "
    109                                           "This used to be a fatal BitlBee bug, but we tried to fix it. "
    110                                           "This message should *never* appear anymore. "
    111                                           "If it does, please *do* send us a bug report! "
    112                                           "Please send all the following lines in your report:" );
    113                        
    114                         irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle );
     109                        irc_usermsg( acc->irc, "WARNING: Almost had an infinite loop in nick_get()! "
     110                                               "This used to be a fatal BitlBee bug, but we tried to fix it. "
     111                                               "This message should *never* appear anymore. "
     112                                               "If it does, please *do* send us a bug report! "
     113                                               "Please send all the following lines in your report:" );
     114                       
     115                        irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );
    115116                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
    116                                 irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
    117                        
    118                         irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "
    119                                           "Good luck, and please don't forget to paste the lines up here "
    120                                           "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
     117                                irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );
     118                       
     119                        irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "
     120                                               "Good luck, and please don't forget to paste the lines up here "
     121                                               "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
    121122                       
    122123                        g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
     
    126127        }
    127128       
    128         return( nick );
    129 }
    130 
    131 void nick_del( irc_t *irc, const char *nick )
    132 {
    133         nick_t *l = NULL, *n = irc->nicks;
    134        
    135         while( n )
    136         {
    137                 if( g_strcasecmp( n->nick, nick ) == 0 )
    138                 {
    139                         if( l )
    140                                 l->next = n->next;
    141                         else
    142                                 irc->nicks = n->next;
    143                        
    144                         g_free( n->handle );
    145                         g_free( n->nick );
    146                         g_free( n );
    147                        
    148                         break;
    149                 }
    150                 n = (l=n)->next;
    151         }
     129        return nick;
     130}
     131
     132void nick_del( account_t *acc, const char *handle )
     133{
     134        g_hash_table_remove( acc->nicks, handle );
    152135}
    153136
  • nick.h

    rf4aa393 rd8d63a2  
    2424*/
    2525
    26 typedef struct __NICK
    27 {
    28         char *handle;
    29         struct prpl *proto;
    30         char *nick;
    31         struct __NICK *next;
    32 } nick_t;
    33 
    34 void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick );
    35 char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname );
    36 void nick_del( irc_t *irc, const char *nick );
     26void nick_set( account_t *acc, const char *handle, const char *nick );
     27char *nick_get( account_t *acc, const char *handle, const char *realname );
     28void nick_del( account_t *acc, const char *handle );
    3729void nick_strip( char *nick );
    3830
  • protocols/Makefile

    rf4aa393 rd8d63a2  
    1010
    1111# [SH] Program variables
    12 objects = $(EVENT_HANDLER) http_client.o md5.o nogaim.o proxy.o sha.o $(SSL_CLIENT)
     12objects = nogaim.o
    1313
    1414# [SH] The next two lines should contain the directory name (in $(subdirs))
  • protocols/jabber/jabber.c

    rf4aa393 rd8d63a2  
    561561static void gjab_start(gjconn gjc)
    562562{
    563         struct aim_user *user;
     563        account_t *acc;
    564564        int port = -1, ssl = 0;
    565         char *server = NULL, *s;
     565        char *server = NULL;
    566566
    567567        if (!gjc || gjc->state != JCONN_STATE_OFF)
    568568                return;
    569569
    570         user = GJ_GC(gjc)->user;
    571         if (*user->proto_opt[0]) {
    572                 /* If there's a dot, assume there's a hostname in the beginning */
    573                 if (strchr(user->proto_opt[0], '.')) {
    574                         server = g_strdup(user->proto_opt[0]);
    575                         if ((s = strchr(server, ':')))
    576                                 *s = 0;
    577                 }
    578                
    579                 /* After the hostname, there can be a port number */
    580                 s = strchr(user->proto_opt[0], ':');
    581                 if (s && isdigit(s[1]))
    582                         sscanf(s + 1, "%d", &port);
    583                
    584                 /* And if there's the string ssl, the user wants an SSL-connection */
    585                 if (strstr(user->proto_opt[0], ":ssl") || g_strcasecmp(user->proto_opt[0], "ssl") == 0)
    586                         ssl = 1;
    587         }
    588        
    589         if (port == -1 && !ssl)
    590                 port = DEFAULT_PORT;
    591         else if (port == -1 && ssl)
    592                 port = DEFAULT_PORT_SSL;
    593         else if (port < JABBER_PORT_MIN || port > JABBER_PORT_MAX) {
     570        acc = GJ_GC(gjc)->acc;
     571        server = acc->server;
     572        port = set_getint(&acc->set, "port");
     573        ssl = set_getbool(&acc->set, "ssl");
     574       
     575        if (port < JABBER_PORT_MIN || port > JABBER_PORT_MAX) {
    594576                serv_got_crap(GJ_GC(gjc), "For security reasons, the Jabber port number must be in the %d-%d range.", JABBER_PORT_MIN, JABBER_PORT_MAX);
    595577                STATE_EVT(JCONN_STATE_OFF)
     
    614596        }
    615597       
    616         g_free(server);
    617        
    618         if (!user->gc || (gjc->fd < 0)) {
     598        if (!acc->gc || (gjc->fd < 0)) {
    619599                STATE_EVT(JCONN_STATE_OFF)
    620600                return;
     
    15161496}
    15171497
    1518 static void jabber_login(struct aim_user *user)
    1519 {
    1520         struct gaim_connection *gc = new_gaim_conn(user);
    1521         struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1);
    1522         char *loginname = create_valid_jid(user->username, DEFAULT_SERVER, "BitlBee");
    1523 
     1498static void jabber_acc_init(account_t *acc)
     1499{
     1500        set_t *s;
     1501       
     1502        s = set_add( &acc->set, "port", "5222", set_eval_int, acc );
     1503        s->flags |= ACC_SET_OFFLINE_ONLY;
     1504       
     1505        s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );
     1506        s->flags |= ACC_SET_OFFLINE_ONLY;
     1507       
     1508        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
     1509        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
     1510       
     1511        s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc );
     1512        s->flags |= ACC_SET_OFFLINE_ONLY;
     1513}
     1514
     1515static void jabber_login(account_t *acc)
     1516{
     1517        struct gaim_connection *gc;
     1518        struct jabber_data *jd;
     1519        char *resource, *loginname;
     1520       
     1521        /* Time to move some data/things from the old syntax to the new one: */
     1522        if (acc->server) {
     1523                char *s, *tmp_server;
     1524                int port;
     1525               
     1526                if (g_strcasecmp(acc->server, "ssl") == 0) {
     1527                        set_setstr(&acc->set, "server", "");
     1528                        set_setint(&acc->set, "port", DEFAULT_PORT_SSL);
     1529                        set_setstr(&acc->set, "ssl", "true");
     1530                       
     1531                        g_free(acc->server);
     1532                        acc->server = NULL;
     1533                } else if ((s = strchr(acc->server, ':'))) {
     1534                        if (strstr(acc->server, ":ssl")) {
     1535                                set_setint(&acc->set, "port", DEFAULT_PORT_SSL);
     1536                                set_setstr(&acc->set, "ssl", "true");
     1537                        }
     1538                        if (isdigit(s[1])) {
     1539                                if (sscanf(s + 1, "%d", &port) == 1)
     1540                                        set_setint(&acc->set, "port", port);
     1541                        }
     1542                        tmp_server = g_strndup(acc->server, s - acc->server);
     1543                        set_setstr(&acc->set, "server", tmp_server);
     1544                        g_free(tmp_server);
     1545                }
     1546        }
     1547       
     1548        gc = new_gaim_conn(acc);
     1549        jd = gc->proto_data = g_new0(struct jabber_data, 1);
     1550       
     1551        if( strchr( acc->user, '@' ) == NULL )
     1552        {
     1553                hide_login_progress( gc, "Invalid account name" );
     1554                signoff( gc );
     1555                return;
     1556        }
     1557       
     1558        resource = set_getstr(&acc->set, "resource");
     1559        loginname = create_valid_jid(acc->user, DEFAULT_SERVER, resource);
     1560       
    15241561        jd->hash = g_hash_table_new(g_str_hash, g_str_equal);
    15251562        jd->chats = NULL;       /* we have no chats yet */
     
    15271564        set_login_progress(gc, 1, _("Connecting"));
    15281565
    1529         if (!(jd->gjc = gjab_new(loginname, user->password, gc))) {
     1566        if (!(jd->gjc = gjab_new(loginname, acc->pass, gc))) {
    15301567                g_free(loginname);
    15311568                hide_login_progress(gc, _("Unable to connect"));
     
    23372374        ret->name = "jabber";
    23382375        ret->away_states = jabber_away_states;
     2376        ret->acc_init = jabber_acc_init;
    23392377        ret->login = jabber_login;
    23402378        ret->close = jabber_close;
     
    23492387        ret->alias_buddy = jabber_roster_update;
    23502388        ret->group_buddy = jabber_group_change;
    2351         ret->cmp_buddynames = g_strcasecmp;
     2389        ret->handle_cmp = g_strcasecmp;
    23522390
    23532391        register_protocol (ret);
  • protocols/msn/msn.c

    rf4aa393 rd8d63a2  
    2727#include "msn.h"
    2828
    29 static void msn_login( struct aim_user *acct )
    30 {
    31         struct gaim_connection *gc = new_gaim_conn( acct );
     29static char *msn_set_display_name( set_t *set, char *value );
     30
     31static void msn_acc_init( account_t *acc )
     32{
     33        set_t *s;
     34       
     35        s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc );
     36        s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;
     37}
     38
     39static void msn_login( account_t *acc )
     40{
     41        struct gaim_connection *gc = new_gaim_conn( acc );
    3242        struct msn_data *md = g_new0( struct msn_data, 1 );
    33        
    34         set_login_progress( gc, 1, "Connecting" );
    3543       
    3644        gc->proto_data = md;
    3745        md->fd = -1;
    3846       
    39         if( strchr( acct->username, '@' ) == NULL )
     47        if( strchr( acc->user, '@' ) == NULL )
    4048        {
    4149                hide_login_progress( gc, "Invalid account name" );
     
    4452        }
    4553       
     54        set_login_progress( gc, 1, "Connecting" );
     55       
    4656        md->fd = proxy_connect( "messenger.hotmail.com", 1863, msn_ns_connected, gc );
    4757        if( md->fd < 0 )
     
    4959                hide_login_progress( gc, "Could not connect to server" );
    5060                signoff( gc );
    51         }
    52         else
    53         {
    54                 md->gc = gc;
    55                 md->away_state = msn_away_state_list;
    56                
    57                 msn_connections = g_slist_append( msn_connections, gc );
    58         }
     61                return;
     62        }
     63       
     64        md->gc = gc;
     65        md->away_state = msn_away_state_list;
     66       
     67        msn_connections = g_slist_append( msn_connections, gc );
    5968}
    6069
     
    212221static void msn_set_info( struct gaim_connection *gc, char *info )
    213222{
    214         int i;
    215         char buf[1024], *fn, *s;
    216         struct msn_data *md = gc->proto_data;
    217        
    218         if( strlen( info ) > 129 )
    219         {
    220                 do_error_dialog( gc, "Maximum name length exceeded", "MSN" );
    221                 return;
    222         }
    223        
    224         /* Of course we could use http_encode() here, but when we encode
    225            every character, the server is less likely to complain about the
    226            chosen name. However, the MSN server doesn't seem to like escaped
    227            non-ASCII chars, so we keep those unescaped. */
    228         s = fn = g_new0( char, strlen( info ) * 3 + 1 );
    229         for( i = 0; info[i]; i ++ )
    230                 if( info[i] & 128 )
    231                 {
    232                         *s = info[i];
    233                         s ++;
    234                 }
    235                 else
    236                 {
    237                         g_snprintf( s, 4, "%%%02X", info[i] );
    238                         s += 3;
    239                 }
    240        
    241         g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
    242         msn_write( gc, buf, strlen( buf ) );
    243         g_free( fn );
     223        msn_set_display_name( set_find( &gc->acc->set, "display_name" ), info );
    244224}
    245225
     
    380360}
    381361
     362static char *msn_set_display_name( set_t *set, char *value )
     363{
     364        account_t *acc = set->data;
     365        struct gaim_connection *gc = acc->gc;
     366        struct msn_data *md;
     367        char buf[1024], *fn;
     368       
     369        /* Double-check. */
     370        if( gc == NULL )
     371                return NULL;
     372       
     373        md = gc->proto_data;
     374       
     375        if( strlen( value ) > 129 )
     376        {
     377                serv_got_crap( gc, "Maximum name length exceeded" );
     378                return NULL;
     379        }
     380       
     381        fn = msn_http_encode( value );
     382       
     383        g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
     384        msn_write( gc, buf, strlen( buf ) );
     385        g_free( fn );
     386       
     387        /* Returning NULL would be better, because the server still has to
     388           confirm the name change. However, it looks a bit confusing to the
     389           user. */
     390        return value;
     391}
     392
    382393void msn_init()
    383394{
    384395        struct prpl *ret = g_new0(struct prpl, 1);
     396       
    385397        ret->name = "msn";
    386398        ret->login = msn_login;
     399        ret->acc_init = msn_acc_init;
    387400        ret->close = msn_close;
    388401        ret->send_im = msn_send_im;
     
    404417        ret->rem_deny = msn_rem_deny;
    405418        ret->send_typing = msn_send_typing;
    406         ret->cmp_buddynames = g_strcasecmp;
     419        ret->handle_cmp = g_strcasecmp;
    407420
    408421        register_protocol(ret);
  • protocols/msn/msn.h

    rf4aa393 rd8d63a2  
    157157char **msn_linesplit( char *line );
    158158int msn_handler( struct msn_handler_data *h );
     159char *msn_http_encode( const char *input );
    159160
    160161/* tables.c */
  • protocols/msn/msn_util.c

    rf4aa393 rd8d63a2  
    5454{
    5555        struct msn_data *md = gc->proto_data;
    56         GSList *l, **lp = NULL;
    5756        char buf[1024], *realname;
    5857       
    59         if( strcmp( list, "AL" ) == 0 )
    60                 lp = &gc->permit;
    61         else if( strcmp( list, "BL" ) == 0 )
    62                 lp = &gc->deny;
    63        
    64         if( lp )
    65                 for( l = *lp; l; l = l->next )
    66                         if( g_strcasecmp( l->data, who ) == 0 )
    67                                 return( 1 );
    68        
    69         realname = g_new0( char, strlen( realname_ ) * 3 + 1 );
    70         strcpy( realname, realname_ );
    71         http_encode( realname );
     58        realname = msn_http_encode( realname_ );
    7259       
    7360        g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s\r\n", ++md->trId, list, who, realname );
     
    7663                g_free( realname );
    7764               
    78                 if( lp )
    79                         *lp = g_slist_append( *lp, g_strdup( who ) );
    80                
    8165                return( 1 );
    8266        }
     
    9074{
    9175        struct msn_data *md = gc->proto_data;
    92         GSList *l = NULL, **lp = NULL;
    9376        char buf[1024];
    94        
    95         if( strcmp( list, "AL" ) == 0 )
    96                 lp = &gc->permit;
    97         else if( strcmp( list, "BL" ) == 0 )
    98                 lp = &gc->deny;
    99        
    100         if( lp )
    101         {
    102                 for( l = *lp; l; l = l->next )
    103                         if( g_strcasecmp( l->data, who ) == 0 )
    104                                 break;
    105                
    106                 if( !l )
    107                         return( 1 );
    108         }
    10977       
    11078        g_snprintf( buf, sizeof( buf ), "REM %d %s %s\r\n", ++md->trId, list, who );
    11179        if( msn_write( gc, buf, strlen( buf ) ) )
    112         {
    113                 if( lp )
    114                         *lp = g_slist_remove( *lp, l->data );
    115                
    11680                return( 1 );
    117         }
    11881       
    11982        return( 0 );
     
    350313        return( 1 );
    351314}
     315
     316/* The difference between this function and the normal http_encode() function
     317   is that this one escapes every 7-bit ASCII character because this is said
     318   to avoid some lame server-side checks when setting a real-name. Also,
     319   non-ASCII characters are not escaped because MSN servers don't seem to
     320   appreciate that! */
     321char *msn_http_encode( const char *input )
     322{
     323        char *ret, *s;
     324        int i;
     325       
     326        ret = s = g_new0( char, strlen( input ) * 3 + 1 );
     327        for( i = 0; input[i]; i ++ )
     328                if( input[i] & 128 )
     329                {
     330                        *s = input[i];
     331                        s ++;
     332                }
     333                else
     334                {
     335                        g_snprintf( s, 4, "%%%02X", input[i] );
     336                        s += 3;
     337                }
     338       
     339        return ret;
     340}
  • protocols/msn/ns.c

    rf4aa393 rd8d63a2  
    223223                else if( num_parts == 7 && strcmp( cmd[2], "OK" ) == 0 )
    224224                {
     225                        set_t *s;
     226                       
    225227                        http_decode( cmd[4] );
    226228                       
    227229                        strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) );
    228230                        gc->displayname[sizeof(gc->displayname)-1] = 0;
     231                       
     232                        if( ( s = set_find( &gc->acc->set, "display_name" ) ) )
     233                        {
     234                                g_free( s->value );
     235                                s->value = g_strdup( cmd[4] );
     236                        }
    229237                       
    230238                        set_login_progress( gc, 1, "Authenticated, getting buddy list" );
     
    517525                if( g_strcasecmp( cmd[3], gc->username ) == 0 )
    518526                {
     527                        set_t *s;
     528                       
    519529                        http_decode( cmd[4] );
    520530                        strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) );
    521531                        gc->displayname[sizeof(gc->displayname)-1] = 0;
     532                       
     533                        if( ( s = set_find( &gc->acc->set, "display_name" ) ) )
     534                        {
     535                                g_free( s->value );
     536                                s->value = g_strdup( cmd[4] );
     537                        }
    522538                }
    523539                else
  • protocols/msn/passport.c

    rf4aa393 rd8d63a2  
    5959        rep->data = data;
    6060        rep->func = func;
     61        rep->header = header;
    6162       
    6263        server = g_strdup( prd_cached );
     
    125126static char *passport_create_header( char *cookie, char *email, char *pwd )
    126127{
    127         char *buffer = g_new0( char, 2048 );
     128        char *buffer;
    128129        char *currenttoken;
    129130        char *email_enc, *pwd_enc;
     131       
     132        currenttoken = strstr( cookie, "lc=" );
     133        if( currenttoken == NULL )
     134                return NULL;
    130135       
    131136        email_enc = g_new0( char, strlen( email ) * 3 + 1 );
     
    137142        http_encode( pwd_enc );
    138143       
    139         currenttoken = strstr( cookie, "lc=" );
    140         if( currenttoken == NULL )
    141                 return( NULL );
    142        
    143         g_snprintf( buffer, 2048,
    144                     "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 );
     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 );
    148148       
    149149        g_free( email_enc );
    150150        g_free( pwd_enc );
    151151       
    152         return( buffer );
     152        return buffer;
    153153}
    154154
     
    212212        if( passport_get_id_real( rep->func, rep->data, rep->header ) )
    213213        {
     214                rep->header = NULL;
    214215                destroy_reply( rep );
    215216                return;
  • protocols/nogaim.c

    rf4aa393 rd8d63a2  
    145145/* multi.c */
    146146
    147 struct gaim_connection *new_gaim_conn( struct aim_user *user )
     147struct gaim_connection *new_gaim_conn( account_t *acc )
    148148{
    149149        struct gaim_connection *gc;
    150         account_t *a;
    151150       
    152151        gc = g_new0( struct gaim_connection, 1 );
    153152       
    154         gc->prpl = user->prpl;
    155         g_snprintf( gc->username, sizeof( gc->username ), "%s", user->username );
    156         g_snprintf( gc->password, sizeof( gc->password ), "%s", user->password );
    157         /* [MD] BUGFIX: don't set gc->irc to the global IRC, but use the one from the struct aim_user.
    158          * This fixes daemon mode breakage where IRC doesn't point to the currently active connection.
    159          */
    160         gc->irc = user->irc;
     153        /* Maybe we should get rid of this memory waste later. ;-) */
     154        g_snprintf( gc->username, sizeof( gc->username ), "%s", acc->user );
     155        g_snprintf( gc->password, sizeof( gc->password ), "%s", acc->pass );
     156       
     157        gc->irc = acc->irc;
     158        gc->acc = acc;
     159        acc->gc = gc;
    161160       
    162161        connections = g_slist_append( connections, gc );
    163        
    164         user->gc = gc;
    165         gc->user = user;
    166        
    167         // Find the account_t so we can set its gc pointer
    168         for( a = gc->irc->accounts; a; a = a->next )
    169                 if( ( struct aim_user * ) a->gc == user )
    170                 {
    171                         a->gc = gc;
    172                         break;
    173                 }
    174162       
    175163        return( gc );
     
    189177       
    190178        connections = g_slist_remove( connections, gc );
    191         g_free( gc->user );
    192179        g_free( gc );
    193180}
     
    220207        va_end( params );
    221208
    222         if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
    223             ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
     209        if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
     210            ( ( gc->flags & OPT_CONN_HTML ) && set_getbool( &gc->irc->set, "strip_html" ) ) )
    224211                strip_html( text );
    225212       
    226213        /* Try to find a different connection on the same protocol. */
    227214        for( a = gc->irc->accounts; a; a = a->next )
    228                 if( a->prpl == gc->prpl && a->gc != gc )
     215                if( a->prpl == gc->acc->prpl && a->gc != gc )
    229216                        break;
    230217       
    231218        /* If we found one, include the screenname in the message. */
    232219        if( a )
    233                 irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, text );
     220                irc_usermsg( gc->irc, "%s(%s) - %s", gc->acc->prpl->name, gc->username, text );
    234221        else
    235                 irc_usermsg( gc->irc, "%s - %s", gc->prpl->name, text );
     222                irc_usermsg( gc->irc, "%s - %s", gc->acc->prpl->name, text );
    236223       
    237224        g_free( text );
     
    242229        struct gaim_connection *gc = d;
    243230       
    244         if( gc->prpl && gc->prpl->keepalive )
    245                 gc->prpl->keepalive( gc );
     231        if( gc->acc->prpl->keepalive )
     232                gc->acc->prpl->keepalive( gc );
    246233       
    247234        return TRUE;
     
    297284        b_event_remove( gc->keepalive );
    298285        gc->flags |= OPT_LOGGING_OUT;
     286       
    299287        gc->keepalive = 0;
    300         gc->prpl->close( gc );
     288        gc->acc->prpl->close( gc );
    301289        b_event_remove( gc->inpa );
    302290       
     
    323311                /* Uhm... This is very sick. */
    324312        }
    325         else if( !gc->wants_to_die && set_getint( irc, "auto_reconnect" ) )
    326         {
    327                 int delay = set_getint( irc, "auto_reconnect_delay" );
     313        else if( !gc->wants_to_die && set_getbool( &irc->set, "auto_reconnect" ) &&
     314                 set_getbool( &a->set, "auto_reconnect" ) )
     315        {
     316                int delay = set_getint( &irc->set, "auto_reconnect_delay" );
    328317               
    329318                serv_got_crap( gc, "Reconnecting in %d seconds..", delay );
     
    364353        irc_t *irc = gc->irc;
    365354       
    366         if( set_getint( irc, "debug" ) && 0 ) /* This message is too useless */
     355        if( set_getbool( &irc->set, "debug" ) && 0 ) /* This message is too useless */
    367356                serv_got_crap( gc, "Receiving user add from handle: %s", handle );
    368357       
    369358        if( user_findhandle( gc, handle ) )
    370359        {
    371                 if( set_getint( irc, "debug" ) )
     360                if( set_getbool( &irc->set, "debug" ) )
    372361                        serv_got_crap( gc, "User already exists, ignoring add request: %s", handle );
    373362               
     
    378367       
    379368        memset( nick, 0, MAX_NICK_LENGTH + 1 );
    380         strcpy( nick, nick_get( gc->irc, handle, gc->prpl, realname ) );
     369        strcpy( nick, nick_get( gc->acc, handle, realname ) );
    381370       
    382371        u = user_add( gc->irc, nick );
     
    390379                u->user = g_strndup( handle, s - handle );
    391380        }
    392         else if( gc->user->proto_opt[0] && *gc->user->proto_opt[0] )
     381        else if( gc->acc->server )
    393382        {
    394383                char *colon;
    395384               
    396                 if( ( colon = strchr( gc->user->proto_opt[0], ':' ) ) )
    397                         u->host = g_strndup( gc->user->proto_opt[0],
    398                                              colon - gc->user->proto_opt[0] );
     385                if( ( colon = strchr( gc->acc->server, ':' ) ) )
     386                        u->host = g_strndup( gc->acc->server,
     387                                             colon - gc->acc->server );
    399388                else
    400                         u->host = g_strdup( gc->user->proto_opt[0] );
     389                        u->host = g_strdup( gc->acc->server );
    401390               
    402391                u->user = g_strdup( handle );
     
    409398        else
    410399        {
    411                 u->host = g_strdup( gc->user->prpl->name );
     400                u->host = g_strdup( gc->acc->prpl->name );
    412401                u->user = g_strdup( handle );
    413402        }
     
    457446                u->realname = g_strdup( realname );
    458447               
    459                 if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( gc->irc, "display_namechanges" ) )
     448                if( ( gc->flags & OPT_LOGGED_IN ) && set_getbool( &gc->irc->set, "display_namechanges" ) )
    460449                        serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname );
    461450        }
     
    479468void show_got_added_yes( gpointer w, struct show_got_added_data *data )
    480469{
    481         data->gc->prpl->add_buddy( data->gc, data->handle );
     470        data->gc->acc->prpl->add_buddy( data->gc, data->handle );
    482471        add_buddy( data->gc, NULL, data->handle, data->handle );
    483472       
     
    513502        if( !u )
    514503        {
    515                 if( g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "add" ) == 0 )
     504                if( g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "add" ) == 0 )
    516505                {
    517506                        add_buddy( gc, NULL, handle, NULL );
     
    520509                else
    521510                {
    522                         if( set_getint( gc->irc, "debug" ) || g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "ignore" ) != 0 )
     511                        if( set_getbool( &gc->irc->set, "debug" ) || g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "ignore" ) != 0 )
    523512                        {
    524513                                serv_got_crap( gc, "serv_got_update() for handle %s:", handle );
     
    558547        }
    559548       
    560         if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "oscar") || !strcmp(gc->prpl->name, "icq")) )
     549        if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "oscar" ) == 0 || strcmp( gc->acc->prpl->name, "icq" ) == 0 ) )
    561550        {
    562551                u->away = g_strdup( "Away" );
    563552        }
    564         else if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "jabber") ) )
     553        else if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "jabber" ) == 0 ) )
    565554        {
    566555                if( type & UC_DND )
     
    571560                        u->away = g_strdup( "Away" );
    572561        }
    573         else if( ( type & UC_UNAVAILABLE ) && gc->prpl->get_status_string )
    574         {
    575                 u->away = g_strdup( gc->prpl->get_status_string( gc, type ) );
     562        else if( ( type & UC_UNAVAILABLE ) && gc->acc->prpl->get_status_string )
     563        {
     564                u->away = g_strdup( gc->acc->prpl->get_status_string( gc, type ) );
    576565        }
    577566        else
     
    579568       
    580569        /* LISPy... */
    581         if( ( set_getint( gc->irc, "away_devoice" ) ) &&                /* Don't do a thing when user doesn't want it */
     570        if( ( set_getbool( &gc->irc->set, "away_devoice" ) ) &&         /* Don't do a thing when user doesn't want it */
    582571            ( u->online ) &&                                            /* Don't touch offline people */
    583572            ( ( ( u->online != oo ) && !u->away ) ||                    /* Voice joining people */
    584573              ( ( u->online == oo ) && ( oa == !u->away ) ) ) )         /* (De)voice people changing state */
    585574        {
    586                 irc_write( gc->irc, ":%s!%s@%s MODE %s %cv %s", gc->irc->mynick, gc->irc->mynick, gc->irc->myhost,
     575                irc_write( gc->irc, ":%s MODE %s %cv %s", gc->irc->myhost,
    587576                                                                gc->irc->channel, u->away?'-':'+', u->nick );
    588577        }
     
    598587        if( !u )
    599588        {
    600                 char *h = set_getstr( irc, "handle_unknown" );
     589                char *h = set_getstr( &irc->set, "handle_unknown" );
    601590               
    602591                if( g_strcasecmp( h, "ignore" ) == 0 )
    603592                {
    604                         if( set_getint( irc, "debug" ) )
     593                        if( set_getbool( &irc->set, "debug" ) )
    605594                                serv_got_crap( gc, "Ignoring message from unknown handle %s", handle );
    606595                       
     
    609598                else if( g_strncasecmp( h, "add", 3 ) == 0 )
    610599                {
    611                         int private = set_getint( irc, "private" );
     600                        int private = set_getbool( &irc->set, "private" );
    612601                       
    613602                        if( h[3] )
     
    630619        }
    631620       
    632         if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
    633             ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
     621        if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
     622            ( ( gc->flags & OPT_CONN_HTML ) && set_getbool( &gc->irc->set, "strip_html" ) ) )
    634623                strip_html( msg );
    635624
     
    671660        user_t *u;
    672661       
    673         if( !set_getint( gc->irc, "typing_notice" ) )
     662        if( !set_getbool( &gc->irc->set, "typing_notice" ) )
    674663                return;
    675664       
     
    693682        GList *ir;
    694683       
    695         if( set_getint( gc->irc, "debug" ) )
     684        if( set_getbool( &gc->irc->set, "debug" ) )
    696685                serv_got_crap( gc, "You were removed from conversation %d", (int) id );
    697686       
     
    732721       
    733722        /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
    734         if( g_strcasecmp( who, gc->user->username ) == 0 )
     723        if( g_strcasecmp( who, gc->username ) == 0 )
    735724                return;
    736725       
     
    738727        for( c = gc->conversations; c && c->id != id; c = c->next );
    739728       
    740         if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
    741             ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
     729        if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
     730            ( ( gc->flags & OPT_CONN_HTML ) && set_getbool( &gc->irc->set, "strip_html" ) ) )
    742731                strip_html( msg );
    743732       
     
    772761        g_free( s );
    773762       
    774         if( set_getint( gc->irc, "debug" ) )
     763        if( set_getbool( &gc->irc->set, "debug" ) )
    775764                serv_got_crap( gc, "Creating new conversation: (id=%d,handle=%s)", id, handle );
    776765       
     
    786775        int me = 0;
    787776       
    788         if( set_getint( b->gc->irc, "debug" ) )
     777        if( set_getbool( &b->gc->irc->set, "debug" ) )
    789778                serv_got_crap( b->gc, "User %s added to conversation %d", handle, b->id );
    790779       
    791780        /* It might be yourself! */
    792         if( b->gc->prpl->cmp_buddynames( handle, b->gc->user->username ) == 0 )
     781        if( b->gc->acc->prpl->handle_cmp( handle, b->gc->username ) == 0 )
    793782        {
    794783                u = user_find( b->gc->irc, b->gc->irc->nick );
     
    820809        int me = 0;
    821810       
    822         if( set_getint( b->gc->irc, "debug" ) )
     811        if( set_getbool( &b->gc->irc->set, "debug" ) )
    823812                serv_got_crap( b->gc, "User %s removed from conversation %d (%s)", handle, b->id, reason ? reason : "" );
    824813       
    825814        /* It might be yourself! */
    826         if( g_strcasecmp( handle, b->gc->user->username ) == 0 )
     815        if( g_strcasecmp( handle, b->gc->username ) == 0 )
    827816        {
    828817                u = user_find( b->gc->irc, b->gc->irc->nick );
     
    882871}
    883872
    884 char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value )
    885 {
     873char *set_eval_away_devoice( set_t *set, char *value )
     874{
     875        irc_t *irc = set->data;
    886876        int st;
    887877       
     
    897887        /* Horror.... */
    898888       
    899         if( st != set_getint( irc, "away_devoice" ) )
     889        if( st != set_getbool( &irc->set, "away_devoice" ) )
    900890        {
    901891                char list[80] = "";
     
    917907                                {
    918908                                        for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0;
    919                                         irc_write( irc, ":%s!%s@%s MODE %s %c%s%s",
    920                                                    irc->mynick, irc->mynick, irc->myhost,
     909                                        irc_write( irc, ":%s MODE %s %c%s%s",
     910                                                   irc->myhost,
    921911                                                   irc->channel, pm, v, list );
    922912                                       
     
    933923                /* $v = 'v' x $i */
    934924                for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0;
    935                 irc_write( irc, ":%s!%s@%s MODE %s %c%s%s", irc->mynick, irc->mynick, irc->myhost,
     925                irc_write( irc, ":%s MODE %s %c%s%s", irc->myhost,
    936926                                                            irc->channel, pm, v, list );
    937927        }
    938928       
    939         return( set_eval_bool( irc, set, value ) );
     929        return( set_eval_bool( set, value ) );
    940930}
    941931
     
    957947        }
    958948       
    959         st = gc->prpl->send_im( gc, handle, msg, strlen( msg ), flags );
     949        st = gc->acc->prpl->send_im( gc, handle, msg, strlen( msg ), flags );
    960950        g_free( buf );
    961951       
     
    974964        }
    975965       
    976         st = gc->prpl->chat_send( gc, id, msg );
     966        st = gc->acc->prpl->chat_send( gc, id, msg );
    977967        g_free( buf );
    978968       
     
    988978       
    989979        if( !away ) away = "";
    990         ms = m = gc->prpl->away_states( gc );
     980        ms = m = gc->acc->prpl->away_states( gc );
    991981       
    992982        while( m )
     
    1009999        if( m )
    10101000        {
    1011                 gc->prpl->set_away( gc, m->data, *away ? away : NULL );
     1001                gc->acc->prpl->set_away( gc, m->data, *away ? away : NULL );
    10121002        }
    10131003        else
     
    10161006                if( s )
    10171007                {
    1018                         gc->prpl->set_away( gc, s, away );
    1019                         if( set_getint( gc->irc, "debug" ) )
     1008                        gc->acc->prpl->set_away( gc, s, away );
     1009                        if( set_getbool( &gc->irc->set, "debug" ) )
    10201010                                serv_got_crap( gc, "Setting away state to %s", s );
    10211011                }
    10221012                else
    1023                         gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away );
     1013                        gc->acc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away );
    10241014        }
    10251015       
     
    10731063void bim_add_allow( struct gaim_connection *gc, char *handle )
    10741064{
    1075         if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL )
     1065        if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL )
    10761066        {
    10771067                gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) );
    10781068        }
    10791069       
    1080         gc->prpl->add_permit( gc, handle );
     1070        gc->acc->prpl->add_permit( gc, handle );
    10811071}
    10821072
     
    10851075        GSList *l;
    10861076       
    1087         if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) )
     1077        if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) )
    10881078        {
    10891079                g_free( l->data );
     
    10911081        }
    10921082       
    1093         gc->prpl->rem_permit( gc, handle );
     1083        gc->acc->prpl->rem_permit( gc, handle );
    10941084}
    10951085
    10961086void bim_add_block( struct gaim_connection *gc, char *handle )
    10971087{
    1098         if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL )
     1088        if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL )
    10991089        {
    11001090                gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) );
    11011091        }
    11021092       
    1103         gc->prpl->add_deny( gc, handle );
     1093        gc->acc->prpl->add_deny( gc, handle );
    11041094}
    11051095
     
    11081098        GSList *l;
    11091099       
    1110         if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) )
     1100        if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) )
    11111101        {
    11121102                g_free( l->data );
     
    11141104        }
    11151105       
    1116         gc->prpl->rem_deny( gc, handle );
    1117 }
     1106        gc->acc->prpl->rem_deny( gc, handle );
     1107}
  • protocols/nogaim.h

    rf4aa393 rd8d63a2  
    3939
    4040#include "bitlbee.h"
     41#include "account.h"
    4142#include "proxy.h"
    4243#include "md5.h"
     
    6364struct gaim_connection
    6465{
    65         struct prpl *prpl;
     66        account_t *acc;
    6667        guint32 flags;
    6768       
     
    7879        GSList *deny;
    7980        int permdeny;
    80        
    81         struct aim_user *user;
    8281       
    8382        char username[64];
     
    126125};
    127126
    128 struct aim_user {
    129         char username[64];
    130         char alias[SELF_ALIAS_LEN];
    131         char password[32];
    132         char user_info[2048];
    133         int options;
    134         struct prpl *prpl;
    135         /* prpls can use this to save information about the user,
    136          * like which server to connect to, etc */
    137         char proto_opt[7][256];
    138 
    139         struct gaim_connection *gc;
    140         irc_t *irc;
    141 };
    142 
    143127struct prpl {
    144128        int options;
    145129        const char *name;
    146130
    147         void (* login)          (struct aim_user *);
     131        void (* acc_init)       (account_t *);
     132        void (* login)          (account_t *);
    148133        void (* keepalive)      (struct gaim_connection *);
    149134        void (* close)          (struct gaim_connection *);
     
    180165       
    181166        /* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* */
    182         int (* cmp_buddynames) (const char *who1, const char *who2);
     167        int (* handle_cmp) (const char *who1, const char *who2);
    183168};
    184169
     
    206191
    207192void nogaim_init();
    208 char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value );
     193char *set_eval_away_devoice( set_t *set, char *value );
    209194
    210195gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
     
    212197
    213198/* multi.c */
    214 G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( struct aim_user *user );
     199G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( account_t *acc );
    215200G_MODULE_EXPORT void destroy_gaim_conn( struct gaim_connection *gc );
    216201G_MODULE_EXPORT void set_login_progress( struct gaim_connection *gc, int step, char *msg );
  • protocols/oscar/info.c

    rf4aa393 rd8d63a2  
    261261                if (!identified) {
    262262                        /*FIXME*/
     263                        /*REMOVEME :-)
    263264                        g_strdup_printf("unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
    264265                                        cap[0], cap[1], cap[2], cap[3],
     
    268269                                        cap[10], cap[11], cap[12], cap[13],
    269270                                        cap[14], cap[15]);
    270                        
     271                        */
    271272                }
    272273
  • protocols/oscar/oscar.c

    rf4aa393 rd8d63a2  
    356356}
    357357
    358 static void oscar_login(struct aim_user *user) {
     358static void oscar_acc_init(account_t *acc)
     359{
     360        set_t *s;
     361       
     362        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
     363        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
     364       
     365        if (isdigit(acc->user[0])) {
     366                s = set_add( &acc->set, "web_aware", "false", set_eval_bool, acc );
     367                s->flags |= ACC_SET_OFFLINE_ONLY;
     368        }
     369}
     370
     371static void oscar_login(account_t *acc) {
    359372        aim_session_t *sess;
    360373        aim_conn_t *conn;
    361374        char buf[256];
    362         struct gaim_connection *gc = new_gaim_conn(user);
     375        struct gaim_connection *gc = new_gaim_conn(acc);
    363376        struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1);
    364377
    365         if (isdigit(*user->username)) {
     378        if (isdigit(acc->user[0])) {
    366379                odata->icq = TRUE;
    367380                /* This is odd but it's necessary for a proper do_import and do_export.
    368381                   We don't do those anymore, but let's stick with it, just in case
    369                    it accidentally fixes something else too... */
     382                   it accidentally fixes something else too... </bitlbee> */
    370383                gc->password[8] = 0;
    371384        } else {
     
    390403        }
    391404       
    392         if (g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.icq.com") != 0 &&
    393             g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.oscar.aol.com") != 0) {
    394                 serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",user->proto_opt[USEROPT_AUTH]);
     405        if (acc->server == NULL) {
     406                hide_login_progress(gc, "No servername specified");
     407                signoff(gc);
     408                return;
     409        }
     410       
     411        if (g_strcasecmp(acc->server, "login.icq.com") != 0 &&
     412            g_strcasecmp(acc->server, "login.oscar.aol.com") != 0) {
     413                serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",acc->server);
    395414        }
    396415       
     
    402421
    403422        conn->status |= AIM_CONN_STATUS_INPROGRESS;
    404         conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ?
    405                                         user->proto_opt[USEROPT_AUTH] : AIM_DEFAULT_LOGIN_SERVER,
    406                                  user->proto_opt[USEROPT_AUTHPORT][0] ?
    407                                         atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,
    408                                  oscar_login_connect, gc);
     423        conn->fd = proxy_connect(acc->server, AIM_LOGIN_PORT, oscar_login_connect, gc);
    409424        if (conn->fd < 0) {
    410425                hide_login_progress(gc, _("Couldn't connect to host"));
     
    485500        struct aim_authresp_info *info;
    486501        int i; char *host; int port;
    487         struct aim_user *user;
    488502        aim_conn_t *bosconn;
    489503
    490504        struct gaim_connection *gc = sess->aux_data;
    491505        struct oscar_data *od = gc->proto_data;
    492         user = gc->user;
    493         port = user->proto_opt[USEROPT_AUTHPORT][0] ?
    494                 atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,
     506        port = AIM_LOGIN_PORT;
    495507
    496508        va_start(ap, fr);
     
    871883        struct aim_redirect_data *redir;
    872884        struct gaim_connection *gc = sess->aux_data;
    873         struct aim_user *user = gc->user;
    874885        aim_conn_t *tstconn;
    875886        int i;
     
    877888        int port;
    878889
    879         port = user->proto_opt[USEROPT_AUTHPORT][0] ?
    880                 atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,
    881 
    882890        va_start(ap, fr);
    883891        redir = va_arg(ap, struct aim_redirect_data *);
    884892        va_end(ap);
    885893
     894        port = AIM_LOGIN_PORT;
    886895        for (i = 0; i < (int)strlen(redir->ip); i++) {
    887896                if (redir->ip[i] == ':') {
     
    12421251        channel = va_arg(ap, int);
    12431252        userinfo = va_arg(ap, aim_userinfo_t *);
    1244 
    1245     if (set_getint(sess->aux_data, "debug")) {
    1246         serv_got_crap(sess->aux_data, "channel %i called", channel);
    1247     }
    12481253
    12491254        switch (channel) {
     
    17231728        odata->rights.maxsiglen = odata->rights.maxawaymsglen = (guint)maxsiglen;
    17241729
     1730        /* FIXME: It seems we're not really using this, and it broke now that
     1731           struct aim_user is dead.
    17251732        aim_bos_setprofile(sess, fr->conn, gc->user->user_info, NULL, gaim_caps);
    1726 
     1733        */
     1734       
    17271735        return 1;
    17281736}
     
    22892297        }
    22902298        info_string_append(str, "\n", _("Mobile Phone"), info->mobile);
    2291         info_string_append(str, "\n", _("Gender"), info->gender==1 ? _("Female") : _("Male"));
     2299        info_string_append(str, "\n", _("Gender"), info->gender==1 ? _("Female") : info->gender==2 ? _("Male") : _("Unknown"));
    22922300        if (info->birthyear || info->birthmonth || info->birthday) {
    22932301                char date[30];
     
    26562664        ret->away_states = oscar_away_states;
    26572665        ret->login = oscar_login;
     2666        ret->acc_init = oscar_acc_init;
    26582667        ret->close = oscar_close;
    26592668        ret->send_im = oscar_send_im;
     
    26732682        ret->set_permit_deny = oscar_set_permit_deny;
    26742683        ret->keepalive = oscar_keepalive;
    2675         ret->cmp_buddynames = aim_sncmp;
    26762684        ret->get_status_string = oscar_get_status_string;
    26772685        ret->send_typing = oscar_send_typing;
     2686       
     2687        ret->handle_cmp = aim_sncmp;
    26782688
    26792689        register_protocol(ret);
  • protocols/oscar/rxhandlers.c

    rf4aa393 rd8d63a2  
    112112                /* Following SNAC will be related */
    113113        }
    114 
    115     if (set_getint(sess->aux_data, "debug")) {
    116         serv_got_crap(sess->aux_data, "snac %x/%x received", snac.family, snac.subtype);
    117     }
    118114
    119115        for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
  • protocols/oscar/service.c

    rf4aa393 rd8d63a2  
    732732        guint32 data;
    733733        int tlvlen;
     734        struct gaim_connection *gc = sess ? sess->aux_data : NULL;
    734735
    735736        data = AIM_ICQ_STATE_HIDEIP | status; /* yay for error checking ;^) */
     737       
     738        if (gc && set_getbool(&gc->acc->set, "web_aware"))
     739                data |= AIM_ICQ_STATE_WEBAWARE;
    736740
    737741        tlvlen = aim_addtlvtochain32(&tl, 0x0006, data);
  • protocols/yahoo/libyahoo2.c

    rf4aa393 rd8d63a2  
    8989#define vsnprintf _vsnprintf
    9090#endif
     91
     92#include "base64.h"
    9193
    9294#ifdef USE_STRUCT_CALLBACKS
     
    695697}
    696698
    697 static char base64digits[] =    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    698                                 "abcdefghijklmnopqrstuvwxyz"
    699                                 "0123456789._";
     699/* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
    700700static void to_y64(unsigned char *out, const unsigned char *in, int inlen)
    701 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
    702 {
    703         for (; inlen >= 3; inlen -= 3)
    704                 {
    705                         *out++ = base64digits[in[0] >> 2];
    706                         *out++ = base64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
    707                         *out++ = base64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)];
    708                         *out++ = base64digits[in[2] & 0x3f];
    709                         in += 3;
    710                 }
    711         if (inlen > 0)
    712                 {
    713                         unsigned char fragment;
    714 
    715                         *out++ = base64digits[in[0] >> 2];
    716                         fragment = (in[0] << 4) & 0x30;
    717                         if (inlen > 1)
    718                                 fragment |= in[1] >> 4;
    719                         *out++ = base64digits[fragment];
    720                         *out++ = (inlen < 2) ? '-'
    721                                         : base64digits[(in[1] << 2) & 0x3c];
    722                         *out++ = '-';
    723                 }
    724         *out = '\0';
     701{
     702        base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-");
    725703}
    726704
  • protocols/yahoo/yahoo.c

    rf4aa393 rd8d63a2  
    121121}
    122122
    123 static void byahoo_login( struct aim_user *user )
    124 {
    125         struct gaim_connection *gc = new_gaim_conn( user );
     123static void byahoo_login( account_t *acc )
     124{
     125        struct gaim_connection *gc = new_gaim_conn( acc );
    126126        struct byahoo_data *yd = gc->proto_data = g_new0( struct byahoo_data, 1 );
    127127       
     
    130130       
    131131        set_login_progress( gc, 1, "Connecting" );
    132         yd->y2_id = yahoo_init( user->username, user->password );
     132        yd->y2_id = yahoo_init( acc->user, acc->pass );
    133133        yahoo_login( yd->y2_id, yd->current_status );
    134134}
     
    192192        gc->away = NULL;
    193193       
    194         if( msg )
     194        if( state && msg && g_strcasecmp( state, msg ) != 0 )
    195195        {
    196196                yd->current_status = YAHOO_STATUS_CUSTOM;
    197197                gc->away = "";
    198198        }
    199         if( state )
    200         {
     199        else if( state )
     200        {
     201                /* Set msg to NULL since (if it isn't NULL already) it's equal
     202                   to state. msg must be empty if we want to use an existing
     203                   away state. */
     204                msg = NULL;
     205               
    201206                gc->away = "";
    202207                if( g_strcasecmp( state, "Available" ) == 0 )
     
    235240                yd->current_status = YAHOO_STATUS_AVAILABLE;
    236241       
    237         if( yd->current_status == YAHOO_STATUS_INVISIBLE )
    238                 yahoo_set_away( yd->y2_id, yd->current_status, NULL, gc->away != NULL );
    239         else
    240                 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL );
     242        yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL );
    241243}
    242244
     
    409411        ret->chat_leave = byahoo_chat_leave;
    410412        ret->chat_open = byahoo_chat_open;
    411         ret->cmp_buddynames = g_strcasecmp;
     413
     414        ret->handle_cmp = g_strcasecmp;
    412415       
    413416        register_protocol(ret);
     
    425428                yd = gc->proto_data;
    426429               
    427                 if( !strcmp(gc->prpl->name, "yahoo") && yd->y2_id == id )
     430                if( strcmp( gc->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
    428431                        return( gc );
    429432        }
  • query.c

    rf4aa393 rd8d63a2  
    6363        }
    6464       
    65         if( g_strcasecmp( set_getstr( irc, "query_order" ), "lifo" ) == 0 || irc->queries == q )
     65        if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "lifo" ) == 0 || irc->queries == q )
    6666                query_display( irc, q );
    6767       
     
    172172        query_t *q;
    173173       
    174         if( g_strcasecmp( set_getstr( irc, "query_order" ), "fifo" ) == 0 )
     174        if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "fifo" ) == 0 )
    175175                q = irc->queries;
    176176        else
  • root_commands.c

    rf4aa393 rd8d63a2  
    127127}
    128128
     129static void cmd_account( irc_t *irc, char **cmd );
     130
    129131static void cmd_identify( irc_t *irc, char **cmd )
    130132{
    131133        storage_status_t status = storage_load( irc->nick, cmd[1], irc );
     134        char *account_on[] = { "account", "on", NULL };
    132135       
    133136        switch (status) {
     
    139142                break;
    140143        case STORAGE_OK:
    141                 irc_usermsg( irc, "Password accepted" );
     144                irc_usermsg( irc, "Password accepted, settings and accounts loaded" );
    142145                irc_umode_set( irc, "+R", 1 );
     146                if( set_getbool( &irc->set, "auto_connect" ) )
     147                        cmd_account( irc, account_on );
    143148                break;
     149        case STORAGE_OTHER_ERROR:
    144150        default:
    145                 irc_usermsg( irc, "Something very weird happened" );
     151                irc_usermsg( irc, "Unknown error while loading configuration" );
    146152                break;
    147153        }
     
    163169                       
    164170                case STORAGE_OK:
     171                        irc_usermsg( irc, "Account successfully created" );
    165172                        irc->status |= USTATUS_IDENTIFIED;
    166173                        irc_umode_set( irc, "+R", 1 );
     
    226233
    227234                a = account_add( irc, prpl, cmd[3], cmd[4] );
    228                
    229235                if( cmd[5] )
    230                         a->server = g_strdup( cmd[5] );
     236                        set_setstr( &a->set, "server", cmd[5] );
    231237               
    232238                irc_usermsg( irc, "Account successfully added" );
     
    306312                       
    307313                                for( a = irc->accounts; a; a = a->next )
    308                                         if( !a->gc )
     314                                        if( !a->gc && a->auto_connect )
    309315                                                account_on( irc, a );
    310316                        }
     
    352358                }
    353359        }
     360        else if( g_strcasecmp( cmd[1], "set" ) == 0 )
     361        {
     362                char *acc_handle, *set_name = NULL, *tmp;
     363               
     364                if( !cmd[2] )
     365                {
     366                        irc_usermsg( irc, "Not enough parameters given (need %d)", 2 );
     367                        return;
     368                }
     369               
     370                acc_handle = g_strdup( cmd[2] );
     371                if( ( tmp = strchr( acc_handle, '/' ) ) )
     372                {
     373                        *tmp = 0;
     374                        set_name = tmp + 1;
     375                }
     376                a = account_get( irc, acc_handle );
     377               
     378                if( a == NULL )
     379                {
     380                        g_free( acc_handle );
     381                        irc_usermsg( irc, "Invalid account" );
     382                        return;
     383                }
     384               
     385                if( cmd[3] )
     386                {
     387                        set_t *s = set_find( &a->set, set_name );
     388                       
     389                        if( a->gc && s && s->flags & ACC_SET_OFFLINE_ONLY )
     390                        {
     391                                g_free( acc_handle );
     392                                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" );
     393                                return;
     394                        }
     395                        else if( !a->gc && s && s->flags & ACC_SET_ONLINE_ONLY )
     396                        {
     397                                g_free( acc_handle );
     398                                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" );
     399                                return;
     400                        }
     401                       
     402                        set_setstr( &a->set, set_name, cmd[3] );
     403                       
     404                        if( ( strcmp( cmd[3], "=" ) ) == 0 && cmd[4] )
     405                                irc_usermsg( irc, "Warning: Correct syntax: \002account set <variable> <value>\002 (without =)" );
     406                }
     407                if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */
     408                {
     409                        char *s = set_getstr( &a->set, set_name );
     410                        if( s )
     411                                irc_usermsg( irc, "%s = `%s'", set_name, s );
     412                        else
     413                                irc_usermsg( irc, "%s is empty", set_name );
     414                }
     415                else
     416                {
     417                        set_t *s = a->set;
     418                        while( s )
     419                        {
     420                                if( s->value || s->def )
     421                                        irc_usermsg( irc, "%s = `%s'", s->key, s->value?s->value:s->def );
     422                                else
     423                                        irc_usermsg( irc, "%s is empty", s->key );
     424                                s = s->next;
     425                        }
     426                }
     427               
     428                g_free( acc_handle );
     429        }
    354430        else
    355431        {
     
    394470                else
    395471                {
    396                         nick_set( irc, cmd[2], a->gc->prpl, cmd[3] );
     472                        nick_set( a, cmd[2], cmd[3] );
    397473                }
    398474        }
     
    401477           add them to your *real* (server-side) contact list. */
    402478        if( add_for_real )
    403                 a->gc->prpl->add_buddy( a->gc, cmd[2] );
     479                a->gc->acc->prpl->add_buddy( a->gc, cmd[2] );
    404480               
    405481        add_buddy( a->gc, NULL, cmd[2], cmd[2] );
     
    435511        }
    436512       
    437         if( !gc->prpl->get_info )
     513        if( !gc->acc->prpl->get_info )
    438514        {
    439515                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     
    441517        else
    442518        {
    443                 gc->prpl->get_info( gc, cmd[2] );
     519                gc->acc->prpl->get_info( gc, cmd[2] );
    444520        }
    445521}
     
    476552                else if( u->send_handler == buddy_send_handler )
    477553                {
    478                         nick_set( irc, u->handle, u->gc->prpl, cmd[2] );
     554                        nick_set( u->gc->acc, u->handle, cmd[2] );
    479555                }
    480556               
     
    495571        s = g_strdup( u->handle );
    496572       
    497         u->gc->prpl->remove_buddy( u->gc, u->handle, NULL );
     573        u->gc->acc->prpl->remove_buddy( u->gc, u->handle, NULL );
    498574        user_del( irc, cmd[1] );
    499         nick_del( irc, cmd[1] );
     575        nick_del( u->gc->acc, s );
    500576       
    501577        irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );
     
    552628        }
    553629       
    554         if( !gc->prpl->add_deny || !gc->prpl->rem_permit )
     630        if( !gc->acc->prpl->add_deny || !gc->acc->prpl->rem_permit )
    555631        {
    556632                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     
    580656               
    581657                irc_usermsg( irc, format, "Handle", "Nickname" );
    582                 for( l = a->gc->deny; l; l = l->next )
     658                for( l = a->gc->permit; l; l = l->next )
    583659                {
    584660                        user_t *u = user_findhandle( a->gc, l->data );
     
    611687        }
    612688       
    613         if( !gc->prpl->rem_deny || !gc->prpl->add_permit )
     689        if( !gc->acc->prpl->rem_deny || !gc->acc->prpl->add_permit )
    614690        {
    615691                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     
    666742        if( cmd[1] && cmd[2] )
    667743        {
    668                 set_setstr( irc, cmd[1], cmd[2] );
     744                set_setstr( &irc->set, cmd[1], cmd[2] );
    669745               
    670746                if( ( strcmp( cmd[2], "=" ) ) == 0 && cmd[3] )
     
    673749        if( cmd[1] ) /* else 'forgotten' on purpose.. Must show new value after changing */
    674750        {
    675                 char *s = set_getstr( irc, cmd[1] );
     751                char *s = set_getstr( &irc->set, cmd[1] );
    676752                if( s )
    677753                        irc_usermsg( irc, "%s = `%s'", cmd[1], s );
     754                else
     755                        irc_usermsg( irc, "%s is empty", cmd[1] );
    678756        }
    679757        else
     
    684762                        if( s->value || s->def )
    685763                                irc_usermsg( irc, "%s = `%s'", s->key, s->value?s->value:s->def );
     764                        else
     765                                irc_usermsg( irc, "%s is empty", s->key );
    686766                        s = s->next;
    687767                }
     
    727807                if( online == 1 )
    728808                {
    729                         g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->user->prpl->name );
     809                        g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name );
    730810                        irc_usermsg( irc, format, u->nick, s, "Online" );
    731811                }
     
    738818                if( away == 1 )
    739819                {
    740                         g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->user->prpl->name );
     820                        g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name );
    741821                        irc_usermsg( irc, format, u->nick, s, u->away );
    742822                }
     
    748828                if( offline == 1 )
    749829                {
    750                         g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->user->prpl->name );
     830                        g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name );
    751831                        irc_usermsg( irc, format, u->nick, s, "Offline" );
    752832                }
     
    773853                irc_usermsg( irc, "Your name is `%s'" , a->gc->displayname ? a->gc->displayname : "NULL" );
    774854        }
    775         else if ( !a->gc->prpl->set_info )
     855        else if ( !a->prpl->set_info )
    776856        {
    777857                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
     
    781861                irc_usermsg( irc, "Setting your name to `%s'", cmd[2] );
    782862               
    783                 a->gc->prpl->set_info( a->gc, cmd[2] );
     863                a->prpl->set_info( a->gc, cmd[2] );
    784864        }
    785865}
     
    800880        for( num = 0; q; q = q->next, num ++ )
    801881                if( q->gc ) /* Not necessary yet, but it might come later */
    802                         irc_usermsg( irc, "%d, %s(%s): %s", num, q->gc->prpl->name, q->gc->username, q->question );
     882                        irc_usermsg( irc, "%d, %s(%s): %s", num, q->gc->acc->prpl->name, q->gc->username, q->question );
    803883                else
    804884                        irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
    805 }
    806 
    807 static void cmd_import_buddies( irc_t *irc, char **cmd )
    808 {
    809         struct gaim_connection *gc;
    810         account_t *a;
    811         nick_t *n;
    812        
    813         if( !( a = account_get( irc, cmd[1] ) ) )
    814         {
    815                 irc_usermsg( irc, "Invalid account" );
    816                 return;
    817         }
    818         else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) )
    819         {
    820                 irc_usermsg( irc, "That account is not on-line" );
    821                 return;
    822         }
    823        
    824         if( cmd[2] )
    825         {
    826                 if( g_strcasecmp( cmd[2], "clear" ) == 0 )
    827                 {
    828                         user_t *u;
    829                        
    830                         for( u = irc->users; u; u = u->next )
    831                                 if( u->gc == gc )
    832                                 {
    833                                         u->gc->prpl->remove_buddy( u->gc, u->handle, NULL );
    834                                         user_del( irc, u->nick );
    835                                 }
    836                        
    837                         irc_usermsg( irc, "Old buddy list cleared." );
    838                 }
    839                 else
    840                 {
    841                         irc_usermsg( irc, "Invalid argument: %s", cmd[2] );
    842                         return;
    843                 }
    844         }
    845        
    846         for( n = gc->irc->nicks; n; n = n->next )
    847         {
    848                 if( n->proto == gc->prpl && !user_findhandle( gc, n->handle ) )
    849                 {
    850                         gc->prpl->add_buddy( gc, n->handle );
    851                         add_buddy( gc, NULL, n->handle, NULL );
    852                 }
    853         }
    854        
    855         irc_usermsg( irc, "Sent all add requests. Please wait for a while, the server needs some time to handle all the adds." );
    856885}
    857886
     
    874903        { "blist",          0, cmd_blist,          0 },
    875904        { "nick",           1, cmd_nick,           0 },
    876         { "import_buddies", 1, cmd_import_buddies, 0 },
    877905        { "qlist",          0, cmd_qlist,          0 },
    878906        { NULL }
  • set.c

    rf4aa393 rd8d63a2  
    2626#include "bitlbee.h"
    2727
    28 set_t *set_add( irc_t *irc, char *key, char *def, void *eval )
    29 {
    30         set_t *s = set_find( irc, key );
    31        
    32         if( !s )
    33         {
    34                 if( ( s = irc->set ) )
     28set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data )
     29{
     30        set_t *s = set_find( head, key );
     31       
     32        /* Possibly the setting already exists. If it doesn't exist yet,
     33           we create it. If it does, we'll just change the default. */
     34        if( !s )
     35        {
     36                if( ( s = *head ) )
    3537                {
    3638                        while( s->next ) s = s->next;
    37                         s->next = g_new ( set_t, 1 );
     39                        s->next = g_new0( set_t, 1 );
    3840                        s = s->next;
    3941                }
    4042                else
    4143                {
    42                         s = irc->set = g_new( set_t, 1 );
     44                        s = *head = g_new0( set_t, 1 );
    4345                }
    44                 memset( s, 0, sizeof( set_t ) );
    4546                s->key = g_strdup( key );
    4647        }
     
    5354        if( def ) s->def = g_strdup( def );
    5455       
    55         if( s->eval )
    56         {
    57                 g_free( s->eval );
    58                 s->eval = NULL;
    59         }
    60         if( eval ) s->eval = eval;
    61        
    62         return( s );
    63 }
    64 
    65 set_t *set_find( irc_t *irc, char *key )
    66 {
    67         set_t *s = irc->set;
     56        s->eval = eval;
     57        s->data = data;
     58       
     59        return s;
     60}
     61
     62set_t *set_find( set_t **head, char *key )
     63{
     64        set_t *s = *head;
    6865       
    6966        while( s )
     
    7471        }
    7572       
    76         return( s );
    77 }
    78 
    79 char *set_getstr( irc_t *irc, char *key )
    80 {
    81         set_t *s = set_find( irc, key );
     73        return s;
     74}
     75
     76char *set_getstr( set_t **head, char *key )
     77{
     78        set_t *s = set_find( head, key );
    8279       
    8380        if( !s || ( !s->value && !s->def ) )
    84                 return( NULL );
    85        
    86         return( s->value?s->value:s->def );
    87 }
    88 
    89 int set_getint( irc_t *irc, char *key )
    90 {
    91         char *s = set_getstr( irc, key );
     81                return NULL;
     82       
     83        return s->value ? s->value : s->def;
     84}
     85
     86int set_getint( set_t **head, char *key )
     87{
     88        char *s = set_getstr( head, key );
    9289        int i = 0;
    9390       
    9491        if( !s )
    95                 return( 0 );
     92                return 0;
    9693       
    9794        if( ( g_strcasecmp( s, "true" ) == 0 ) || ( g_strcasecmp( s, "yes" ) == 0 ) || ( g_strcasecmp( s, "on" ) == 0 ) )
    98                 return( 1 );
     95                return 1;
    9996       
    10097        if( sscanf( s, "%d", &i ) != 1 )
    101                 return( 0 );
    102        
    103         return( i );
    104 }
    105 
    106 int set_setstr( irc_t *irc, char *key, char *value )
    107 {
    108         set_t *s = set_find( irc, key );
     98                return 0;
     99       
     100        return i;
     101}
     102
     103int set_getbool( set_t **head, char *key )
     104{
     105        char *s = set_getstr( head, key );
     106       
     107        if( !s )
     108                return 0;
     109       
     110        return bool2int( s );
     111}
     112
     113int set_setstr( set_t **head, char *key, char *value )
     114{
     115        set_t *s = set_find( head, key );
    109116        char *nv = value;
    110117       
    111118        if( !s )
    112                 s = set_add( irc, key, NULL, NULL );
    113        
    114         if( s->eval && !( nv = s->eval( irc, s, value ) ) )
    115                 return( 0 );
     119                s = set_add( head, key, NULL, NULL, NULL );
     120       
     121        if( s->eval && !( nv = s->eval( s, value ) ) )
     122                return 0;
    116123       
    117124        if( s->value )
     
    121128        }
    122129       
     130        /* If there's a default setting and it's equal to what we're trying to
     131           set, stick with s->value = NULL. Otherwise, remember the setting. */
    123132        if( !s->def || ( strcmp( nv, s->def ) != 0 ) )
    124133                s->value = g_strdup( nv );
     
    127136                g_free( nv );
    128137       
    129         return( 1 );
    130 }
    131 
    132 int set_setint( irc_t *irc, char *key, int value )
     138        return 1;
     139}
     140
     141int set_setint( set_t **head, char *key, int value )
    133142{
    134143        char s[24];     /* Not quite 128-bit clean eh? ;-) */
    135144       
    136         sprintf( s, "%d", value );
    137         return( set_setstr( irc, key, s ) );
    138 }
    139 
    140 void set_del( irc_t *irc, char *key )
    141 {
    142         set_t *s = irc->set, *t = NULL;
     145        g_snprintf( s, sizeof( s ), "%d", value );
     146        return set_setstr( head, key, s );
     147}
     148
     149void set_del( set_t **head, char *key )
     150{
     151        set_t *s = *head, *t = NULL;
    143152       
    144153        while( s )
     
    153162                        t->next = s->next;
    154163                else
    155                         irc->set = s->next;
     164                        *head = s->next;
    156165               
    157166                g_free( s->key );
     
    162171}
    163172
    164 char *set_eval_int( irc_t *irc, set_t *set, char *value )
     173char *set_eval_int( set_t *set, char *value )
    165174{
    166175        char *s = value;
    167176       
     177        /* Allow a minus at the first position. */
     178        if( *s == '-' )
     179                s ++;
     180       
    168181        for( ; *s; s ++ )
    169                 if( *s < '0' || *s > '9' )
    170                         return( NULL );
    171        
    172         return( value );
    173 }
    174 
    175 char *set_eval_bool( irc_t *irc, set_t *set, char *value )
    176 {
    177         if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
    178                 return( value );
    179         if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
    180                 return( value );
    181         return( set_eval_int( irc, set, value ) );
    182 }
    183 
    184 char *set_eval_to_char( irc_t *irc, set_t *set, char *value )
     182                if( !isdigit( *s ) )
     183                        return NULL;
     184       
     185        return value;
     186}
     187
     188char *set_eval_bool( set_t *set, char *value )
     189{
     190        return is_bool( value ) ? value : NULL;
     191}
     192
     193char *set_eval_to_char( set_t *set, char *value )
    185194{
    186195        char *s = g_new( char, 3 );
     
    191200                sprintf( s, "%c ", *value );
    192201       
    193         return( s );
    194 }
    195 
    196 char *set_eval_ops( irc_t *irc, set_t *set, char *value )
    197 {
     202        return s;
     203}
     204
     205char *set_eval_ops( set_t *set, char *value )
     206{
     207        irc_t *irc = set->data;
     208       
    198209        if( g_strcasecmp( value, "user" ) == 0 )
    199         {
    200210                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    201211                                                              irc->channel, "+o-o", irc->nick, irc->mynick );
    202                 return( value );
    203         }
    204212        else if( g_strcasecmp( value, "root" ) == 0 )
    205         {
    206213                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    207214                                                              irc->channel, "-o+o", irc->nick, irc->mynick );
    208                 return( value );
    209         }
    210215        else if( g_strcasecmp( value, "both" ) == 0 )
    211         {
    212216                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    213217                                                              irc->channel, "+oo", irc->nick, irc->mynick );
    214                 return( value );
    215         }
    216218        else if( g_strcasecmp( value, "none" ) == 0 )
    217         {
    218219                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    219220                                                              irc->channel, "-oo", irc->nick, irc->mynick );
    220                 return( value );
    221         }
    222        
    223         return( NULL );
    224 }
    225 
     221        else
     222                return NULL;
     223       
     224        return value;
     225}
     226
     227char *set_eval_charset( set_t *set, char *value )
     228{
     229        GIConv cd;
     230
     231        if ( g_strncasecmp( value, "none", 4 ) == 0 )
     232                return value;
     233
     234        cd = g_iconv_open( "UTF-8", value );
     235        if( cd == (GIConv) -1 )
     236                return NULL;
     237
     238        g_iconv_close( cd );
     239        return value;
     240}
  • set.h

    rf4aa393 rd8d63a2  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2424*/
    2525
     26/* This used to be specific to irc_t structures, but it's more generic now
     27   (so it can also be used for account_t structs). It's pretty simple, but
     28   so far pretty useful.
     29   
     30   In short, it just keeps a linked list of settings/variables and it also
     31   remembers a default value for every setting. And to prevent the user
     32   from setting invalid values, you can write an evaluator function for
     33   every setting, which can check a new value and block it by returning
     34   NULL, or replace it by returning a new value. See struct set.eval. */
     35
     36typedef char *(*set_eval) ( struct set *set, char *value );
     37
    2638typedef struct set
    2739{
     40        void *data;     /* Here you can save a pointer to the
     41                           object this settings belongs to. */
     42       
    2843        char *key;
    2944        char *value;
    30         char *def;      /* Default */
     45        char *def;      /* Default value. If the set_setstr() function
     46                           notices a new value is exactly the same as
     47                           the default, value gets set to NULL. So when
     48                           you read a setting, don't forget about this! */
    3149       
    32         /* Eval: Returns NULL if the value is incorrect. Can return a
    33            corrected value. set_setstr() should be able to free() the
    34            returned string! */
    35         char *(*eval) ( irc_t *irc, struct set *set, char *value );
     50        int flags;      /* See account.h, for example. set.c doesn't use
     51                           this (yet?). */
     52       
     53        /* Eval: Returns NULL if the value is incorrect or exactly the
     54           passed value variable. When returning a corrected value,
     55           set_setstr() should be able to free() the returned string! */
     56        set_eval eval;
    3657        struct set *next;
    3758} set_t;
    3859
    39 set_t *set_add( irc_t *irc, char *key, char *def, void *eval );
    40 G_MODULE_EXPORT set_t *set_find( irc_t *irc, char *key );
    41 G_MODULE_EXPORT char *set_getstr( irc_t *irc, char *key );
    42 G_MODULE_EXPORT int set_getint( irc_t *irc, char *key );
    43 int set_setstr( irc_t *irc, char *key, char *value );
    44 int set_setint( irc_t *irc, char *key, int value );
    45 void set_del( irc_t *irc, char *key );
     60/* Should be pretty clear. */
     61set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data );
    4662
    47 char *set_eval_int( irc_t *irc, set_t *set, char *value );
    48 char *set_eval_bool( irc_t *irc, set_t *set, char *value );
    49 char *set_eval_to_char( irc_t *irc, set_t *set, char *value );
    50 char *set_eval_ops( irc_t *irc, set_t *set, char *value );
     63/* Returns the raw set_t. Might be useful sometimes. */
     64set_t *set_find( set_t **head, char *key );
    5165
     66/* Returns a pointer to the string value of this setting. Don't modify the
     67   returned string, and don't free() it! */
     68G_MODULE_EXPORT char *set_getstr( set_t **head, char *key );
    5269
     70/* Get an integer. Right now this also converts true/false/on/off/etc to
     71   numbers, but this is for historical reasons, please use set_getbool()
     72   for booleans instead. */
     73G_MODULE_EXPORT int set_getint( set_t **head, char *key );
     74G_MODULE_EXPORT int set_getbool( set_t **head, char *key );
     75
     76/* set_setstr() strdup()s the given value, so after using this function
     77   you can free() it, if you want. */
     78int set_setstr( set_t **head, char *key, char *value );
     79int set_setint( set_t **head, char *key, int value );
     80void set_del( set_t **head, char *key );
     81
     82/* Two very useful generic evaluators. */
     83char *set_eval_int( set_t *set, char *value );
     84char *set_eval_bool( set_t *set, char *value );
     85
     86/* Some not very generic evaluators that really shouldn't be here... */
     87char *set_eval_to_char( set_t *set, char *value );
     88char *set_eval_ops( set_t *set, char *value );
     89char *set_eval_charset( set_t *set, char *value );
  • sock.h

    rf4aa393 rd8d63a2  
    11#include <errno.h>
    22#include <fcntl.h>
    3 
    4 /* To cut down on the ifdef stuff a little bit in other places */
    5 #ifdef IPV6
    6 #define AF_INETx AF_INET6
    7 #else
    8 #define AF_INETx AF_INET
    9 #endif
    103
    114#ifndef _WIN32
  • storage.c

    rf4aa393 rd8d63a2  
    66
    77/* Support for multiple storage backends */
     8
     9/* Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org> */
    810
    911/*
     
    2931
    3032extern storage_t storage_text;
     33extern storage_t storage_xml;
    3134
    32 static GList text_entry = { &storage_text, NULL, NULL };
    33 static GList *storage_backends = &text_entry;
     35static GList *storage_backends = NULL;
    3436
    3537void register_storage_backend(storage_t *backend)
     
    4143{
    4244        GList *gl;
    43         storage_t *st;
     45        storage_t *st = NULL;
    4446
    4547        for (gl = storage_backends; gl; gl = gl->next) {
     
    6365        int i;
    6466        storage_t *storage;
    65 
     67       
     68        register_storage_backend(&storage_text);
     69        register_storage_backend(&storage_xml);
     70       
    6671        storage = storage_init_single(primary);
    67         if (storage == NULL)
     72        if (storage == NULL && storage->save == NULL)
    6873                return NULL;
    6974
  • storage.h

    rf4aa393 rd8d63a2  
    3333        STORAGE_ALREADY_EXISTS,
    3434        STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as
    35                                                    a database that is unreachable. log() will be
    36                                                    used for the exact error message */
     35                               a database that is unreachable. log() will be
     36                               used for the exact error message */
    3737} storage_status_t;
    3838
  • storage_text.c

    rf4aa393 rd8d63a2  
    2828#include "crypting.h"
    2929
    30 /* DO NOT USE THIS FUNCTION IN NEW CODE. This
    31  * function is here merely because the save/load code still uses
    32  * ids rather than names */
    33 static struct prpl *find_protocol_by_id(int id)
    34 {
    35         switch (id) {
    36         case 0: case 1: case 3: return find_protocol("oscar");
    37         case 4: return find_protocol("msn");
    38         case 2: return find_protocol("yahoo");
    39         case 8: return find_protocol("jabber");
    40         default: break;
    41         }
    42         return NULL;
    43 }
    44 
    45 static int find_protocol_id(const char *name)
    46 {
    47         if (!strcmp(name, "oscar")) return 1;
    48         if (!strcmp(name, "msn")) return 4;
    49         if (!strcmp(name, "yahoo")) return 2;
    50         if (!strcmp(name, "jabber")) return 8;
    51 
    52         return -1;
    53 }
    54 
    55 
    5630static void text_init (void)
    5731{
    5832        if( access( global.conf->configdir, F_OK ) != 0 )
    59                 log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", CONFIG );
     33                log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", global.conf->configdir );
    6034        else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
    6135                log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
     
    7044        FILE *fp;
    7145        user_t *ru = user_find( irc, ROOT_NICK );
     46        account_t *acc, *acc_lookup[9];
    7247       
    7348        if( irc->status & USTATUS_IDENTIFIED )
     
    8055        fscanf( fp, "%32[^\n]s", s );
    8156
    82         if (checkpass (password, s) != 0)
     57        if( checkpass( password, s ) != 0 )
    8358        {
    8459                fclose( fp );
     
    10075        fclose( fp );
    10176       
     77        /* Build a list with the first listed account of every protocol
     78           number. So if the user had nicks defined for a second account on
     79           the same IM network, those nicks will be added to the wrong
     80           account, and the user should rename those buddies again. But at
     81           least from now on things will be saved properly. */
     82        memset( acc_lookup, 0, sizeof( acc_lookup ) );
     83        for( acc = irc->accounts; acc; acc = acc->next )
     84        {
     85                if( acc_lookup[0] == NULL && strcmp( acc->prpl->name, "oscar" ) == 0 )
     86                        acc_lookup[0] = acc_lookup[1] = acc_lookup[3] = acc;
     87                else if( acc_lookup[2] == NULL && strcmp( acc->prpl->name, "yahoo" ) == 0 )
     88                        acc_lookup[2] = acc;
     89                else if( acc_lookup[4] == NULL && strcmp( acc->prpl->name, "msn" ) == 0 )
     90                        acc_lookup[4] = acc;
     91                else if( acc_lookup[8] == NULL && strcmp( acc->prpl->name, "jabber" ) == 0 )
     92                        acc_lookup[8] = acc;
     93        }
     94       
    10295        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );
    10396        fp = fopen( s, "r" );
     
    10598        while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
    10699        {
    107                 struct prpl *prpl;
    108 
    109                 prpl = find_protocol_by_id(proto);
    110 
    111                 if (!prpl)
     100                if( ( acc = acc_lookup[proto] ) == NULL )
    112101                        continue;
    113 
     102               
    114103                http_decode( s );
    115                 nick_set( irc, s, prpl, nick );
     104                nick_set( acc, s, nick );
    116105        }
    117106        fclose( fp );
    118        
    119         if( set_getint( irc, "auto_connect" ) )
    120         {
    121                 strcpy( s, "account on" );      /* Can't do this directly because r_c_s alters the string */
    122                 root_command_string( irc, ru, s, 0 );
    123         }
    124        
    125         return STORAGE_OK;
    126 }
    127 
    128 static storage_status_t text_save( irc_t *irc, int overwrite )
    129 {
    130         char s[512];
    131         char path[512], new_path[512];
    132         char *line;
    133         nick_t *n;
    134         set_t *set;
    135         mode_t ou = umask( 0077 );
    136         account_t *a;
    137         FILE *fp;
    138         char *hash;
    139 
    140         if (!overwrite) {
    141                 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    142                 if (access( path, F_OK ) != -1)
    143                         return STORAGE_ALREADY_EXISTS;
    144        
    145                 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    146                 if (access( path, F_OK ) != -1)
    147                         return STORAGE_ALREADY_EXISTS;
    148         }
    149        
    150         /*\
    151          *  [SH] Nothing should be saved if no password is set, because the
    152          *  password is not set if it was wrong, or if one is not identified
    153          *  yet. This means that a malicious user could easily overwrite
    154          *  files owned by someone else:
    155          *  a Bad Thing, methinks
    156         \*/
    157 
    158         /* [WVG] No? Really? */
    159 
    160         /*\
    161          *  [SH] Okay, okay, it wasn't really Wilmer who said that, it was
    162          *  me. I just thought it was funny.
    163         \*/
    164        
    165         hash = hashpass( irc->password );
    166         if( hash == NULL )
    167         {
    168                 irc_usermsg( irc, "Please register yourself if you want to save your settings." );
    169                 return STORAGE_OTHER_ERROR;
    170         }
    171        
    172         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
    173         fp = fopen( path, "w" );
    174         if( !fp ) return STORAGE_OTHER_ERROR;
    175         for( n = irc->nicks; n; n = n->next )
    176         {
    177                 strcpy( s, n->handle );
    178                 s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
    179                 http_encode( s );
    180                 g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", find_protocol_id(n->proto->name), n->nick );
    181                 if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
    182                 {
    183                         irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    184                         fclose( fp );
    185                         return STORAGE_OTHER_ERROR;
    186                 }
    187         }
    188         if( fclose( fp ) != 0 )
    189         {
    190                 irc_usermsg( irc, "fclose() reported an error. Disk full?" );
    191                 return STORAGE_OTHER_ERROR;
    192         }
    193  
    194         g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    195         if( unlink( new_path ) != 0 )
    196         {
    197                 if( errno != ENOENT )
    198                 {
    199                         irc_usermsg( irc, "Error while removing old .nicks file" );
    200                         return STORAGE_OTHER_ERROR;
    201                 }
    202         }
    203         if( rename( path, new_path ) != 0 )
    204         {
    205                 irc_usermsg( irc, "Error while renaming new .nicks file" );
    206                 return STORAGE_OTHER_ERROR;
    207         }
    208        
    209         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
    210         fp = fopen( path, "w" );
    211         if( !fp ) return STORAGE_OTHER_ERROR;
    212         if( fprintf( fp, "%s", hash ) != strlen( hash ) )
    213         {
    214                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    215                 fclose( fp );
    216                 return STORAGE_OTHER_ERROR;
    217         }
    218         g_free( hash );
    219 
    220         for( a = irc->accounts; a; a = a->next )
    221         {
    222                 if( !strcmp(a->prpl->name, "oscar") )
    223                         g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
    224                 else
    225                         g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
    226                                     a->prpl->name, a->user, a->pass, a->server ? a->server : "" );
    227                
    228                 line = obfucrypt( s, irc->password );
    229                 if( *line )
    230                 {
    231                         if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    232                         {
    233                                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    234                                 fclose( fp );
    235                                 return STORAGE_OTHER_ERROR;
    236                         }
    237                 }
    238                 g_free( line );
    239         }
    240        
    241         for( set = irc->set; set; set = set->next )
    242         {
    243                 if( set->value && set->def )
    244                 {
    245                         g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
    246                         line = obfucrypt( s, irc->password );
    247                         if( *line )
    248                         {
    249                                 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    250                                 {
    251                                         irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    252                                         fclose( fp );
    253                                         return STORAGE_OTHER_ERROR;
    254                                 }
    255                         }
    256                         g_free( line );
    257                 }
    258         }
    259        
    260         if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
    261         {
    262                 g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
    263                 line = obfucrypt( s, irc->password );
    264                 if( *line )
    265                 {
    266                         if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    267                         {
    268                                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    269                                 fclose( fp );
    270                                 return STORAGE_OTHER_ERROR;
    271                         }
    272                 }
    273                 g_free( line );
    274         }
    275         if( fclose( fp ) != 0 )
    276         {
    277                 irc_usermsg( irc, "fclose() reported an error. Disk full?" );
    278                 return STORAGE_OTHER_ERROR;
    279         }
    280        
    281         g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    282         if( unlink( new_path ) != 0 )
    283         {
    284                 if( errno != ENOENT )
    285                 {
    286                         irc_usermsg( irc, "Error while removing old .accounts file" );
    287                         return STORAGE_OTHER_ERROR;
    288                 }
    289         }
    290         if( rename( path, new_path ) != 0 )
    291         {
    292                 irc_usermsg( irc, "Error while renaming new .accounts file" );
    293                 return STORAGE_OTHER_ERROR;
    294         }
    295        
    296         umask( ou );
    297107       
    298108        return STORAGE_OK;
     
    343153        .check_pass = text_check_pass,
    344154        .remove = text_remove,
    345         .load = text_load,
    346         .save = text_save
     155        .load = text_load
    347156};
  • unix.c

    rf4aa393 rd8d63a2  
    4848       
    4949        b_main_init();
    50        
    5150        log_init();
    52 
    5351  &nbs