Changeset 69cb623


Ignore:
Timestamp:
2006-10-15T09:41:12Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
2529faf
Parents:
695e392 (diff), e97827b (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:

Merging with storage-xml. It seems to be working pretty well, so maybe
this way more people will test it. :-)

Files:
9 added
1 deleted
37 edited
21 moved

Legend:

Unmodified
Added
Removed
  • Makefile

    r695e392 r69cb623  
    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
     
    4242
    4343distclean: clean $(subdirs)
    44         rm -f Makefile.settings config.h
     44        rm -f Makefile.settings config.h bitlbee.pc
    4545        find . -name 'DEADJOE' -o -name '*.orig' -o -name '*.rej' -o -name '*~' -exec rm -f {} \;
    4646
  • account.c

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    310310                        irc_t *irc;
    311311                       
     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                       
    312316                        /* Close the listening socket, we're a client. */
    313317                        close( global.listen_socket );
  • bitlbee.h

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    3131
    3232events=glib
     33ldap=auto
    3334ssl=auto
    3435
     
    6667
    6768--ipv6=0/1      IPv6 socket support                     $ipv6
     69
     70--ldap=0/1/auto LDAP support                            $ldap
    6871
    6972--events=...    Event handler (glib, libevent)          $events
     
    141144fi
    142145
    143 echo CFLAGS+=-I`pwd` -I`pwd`/protocols -I. >> Makefile.settings
     146echo CFLAGS+=-I`pwd` -I`pwd`/lib -I`pwd`/protocols -I. >> Makefile.settings
    144147
    145148echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings
    146149
    147150if [ -n "$CC" ]; then
    148         echo "CC=$CC" >> Makefile.settings;
     151        CC=$CC
    149152elif type gcc > /dev/null 2> /dev/null; then
    150         echo "CC=gcc" >> Makefile.settings;
     153        CC=gcc
    151154elif type cc > /dev/null 2> /dev/null; then
    152         echo "CC=cc" >> Makefile.settings;
     155        CC=cc
    153156else
    154157        echo 'Cannot find a C compiler, aborting.'
    155158        exit 1;
    156159fi
     160
     161echo "CC=$CC" >> Makefile.settings;
    157162
    158163if [ -n "$LD" ]; then
     
    232237}
    233238
    234 if [ "$msn" = 1 -o "$jabber" = 1 ]; then
    235         if [ "$ssl" = "auto" ]; then
    236                 detect_gnutls
    237                 if [ "$ret" = "0" ]; then
    238                         detect_nss
    239                 fi;
    240         elif [ "$ssl" = "gnutls" ]; then
    241                 detect_gnutls;
    242         elif [ "$ssl" = "nss" ]; then
    243                 detect_nss;
    244         elif [ "$ssl" = "openssl" ]; then
     239detect_ldap()
     240{
     241        TMPFILE=`mktemp`
     242        if $CC -o $TMPFILE -shared -lldap 2>/dev/null >/dev/null; then
     243                cat<<EOF>>Makefile.settings
     244EFLAGS+=-lldap
     245CFLAGS+=
     246EOF
     247                ldap=1
     248                rm -f $TMPFILE
     249                ret=1
     250        else
     251                ldap=0
     252                ret=0
     253        fi
     254}
     255
     256if [ "$ssl" = "auto" ]; then
     257        detect_gnutls
     258        if [ "$ret" = "0" ]; then
     259                detect_nss
     260        fi
     261elif [ "$ssl" = "gnutls" ]; then
     262        detect_gnutls
     263elif [ "$ssl" = "nss" ]; then
     264        detect_nss
     265elif [ "$ssl" = "openssl" ]; then
     266        echo
     267        echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
     268        echo 'install of OpenSSL (including devel/header files) before reporting'
     269        echo 'compilation problems.'
     270        echo
     271        echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
     272        echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
     273        echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
     274        echo 'part of the operating system, which makes it GPL-compatible.'
     275        echo
     276        echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
     277        echo '                    http://www.gnome.org/~markmc/openssl-and-the-gpl.html'
     278        echo
     279        echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
     280        echo 'probably illegal. If you want to create and distribute a binary BitlBee'
     281        echo 'package, you really should use GnuTLS or NSS instead.'
     282        echo
     283        echo 'Also, the OpenSSL license requires us to say this:'
     284        echo ' *    "This product includes software developed by the OpenSSL Project'
     285        echo ' *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"'
     286       
     287        echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings
     288       
     289        ret=1
     290elif [ "$ssl" = "bogus" ]; then
     291        echo
     292        echo 'Using bogus SSL code. This means some features have to be disabled.'
     293       
     294        ## Yes, you, at the console! How can you authenticate if you don't have any SSL!?
     295        if [ "$msn" = "1" ]; then
    245296                echo
    246                 echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
    247                 echo 'install of OpenSSL (including devel/header files) before reporting'
    248                 echo 'compilation problems.'
    249                 echo
    250                 echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
    251                 echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
    252                 echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
    253                 echo 'part of the operating system, which makes it GPL-compatible.'
    254                 echo
    255                 echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
    256                 echo '                    http://www.gnome.org/~markmc/openssl-and-the-gpl.html'
    257                 echo
    258                 echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
    259                 echo 'probably illegal. If you want to create and distribute a binary BitlBee'
    260                 echo 'package, you really should use GnuTLS or NSS instead.'
    261                 echo
    262                 echo 'Also, the OpenSSL license requires us to say this:'
    263                 echo ' *    "This product includes software developed by the OpenSSL Project'
    264                 echo ' *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"'
    265                
    266                 echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings
    267                
    268                 ret=1;
    269         elif [ "$ssl" = "bogus" ]; then
    270                 echo
    271                 echo 'Using bogus SSL code. This will not make the MSN module work, but it will'
    272                 echo 'allow you to use the Jabber module - although without working SSL support.'
    273                
    274                 ret=1;
    275         else
    276                 echo
    277                 echo 'ERROR: Unknown SSL library specified.'
    278                 exit 1;
    279         fi
    280        
    281         if [ "$ret" = "0" ]; then
    282                 echo
    283                 echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
    284                 echo '       This is necessary for MSN and full Jabber support. To continue,'
    285                 echo '       install a suitable SSL library or disable MSN support (--msn=0).'
    286                 echo '       If you want Jabber without SSL support you can try --ssl=bogus.'
    287                
    288                 exit 1;
    289         fi;
    290        
    291         echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
    292 fi
     297                echo 'Real SSL support is necessary for MSN authentication, will build without'
     298                echo 'MSN protocol support.'
     299                msn=0
     300        fi
     301       
     302        ret=1
     303else
     304        echo
     305        echo 'ERROR: Unknown SSL library specified.'
     306        exit 1
     307fi
     308
     309if [ "$ret" = "0" ]; then
     310        echo
     311        echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
     312        echo '       Please note that this script doesn'\''t have detection code for OpenSSL,'
     313        echo '       so if you want to use that, you have to select it by hand. If you don'\''t'
     314        echo '       need SSL support, you can select the "bogus" SSL library. (--ssl=bogus)'
     315       
     316        exit 1
     317fi;
     318
     319echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
     320
     321STORAGES="text xml"
     322
     323if [ "$ldap" = "auto" ]; then
     324        detect_ldap
     325fi
     326
     327if [ "$ldap" = 0 ]; then
     328        echo "#undef WITH_LDAP" >> config.h
     329elif [ "$ldap" = 1 ]; then
     330        echo "#define WITH_LDAP 1" >> config.h
     331        STORAGES="$STORAGES ldap"
     332fi
     333
     334for i in $STORAGES; do
     335        STORAGE_OBJS="$STORAGE_OBJS storage_$i.o"
     336done
     337echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings
    293338
    294339if [ "$strip" = 0 ]; then
     
    304349        elif type strip > /dev/null 2> /dev/null; then
    305350                echo "STRIP=strip" >> Makefile.settings;
    306         elif /bin/test -x /usr/ccs/bin/strip; then
    307                 echo "STRIP=/usr/ccs/bin/strip" >> Makefile.settings;
    308351        else
    309352                echo
     
    384427if [ "$protocols" = "PROTOCOLS = " ]; then
    385428        echo "WARNING: You haven't selected any communication protocol to compile!"
    386         echo "         Bitlbee will run, but you will be unable to connect to IM servers!"
     429        echo "         BitlBee will run, but you will be unable to connect to IM servers!"
    387430fi
    388431
     
    419462
    420463if [ "$debug" = "1" ]; then
    421         echo '  Debugging enabled.';
    422 else
    423         echo '  Debugging disabled.';
     464        echo '  Debugging enabled.'
     465else
     466        echo '  Debugging disabled.'
    424467fi
    425468
    426469if [ "$strip" = "1" ]; then
    427         echo '  Binary stripping enabled.';
    428 else
    429         echo '  Binary stripping disabled.';
    430 fi
    431 
    432 echo '  Using event handler: '$events;
    433 echo '  Using SSL library: '$ssl;
    434 
    435 #if [ "$flood" = "0" ]; then
    436 #       echo '  Flood protection disabled.';
    437 #else
    438 #       echo '  Flood protection enabled.';
    439 #fi
     470        echo '  Binary stripping enabled.'
     471else
     472        echo '  Binary stripping disabled.'
     473fi
     474
     475echo '  Using event handler: '$events
     476echo '  Using SSL library: '$ssl
     477echo '  Building with these storage backends: '$STORAGES
    440478
    441479if [ -n "$protocols" ]; then
    442         echo '  Building with these protocols:' $protocols;
    443 else
    444         echo '  Building without IM-protocol support. We wish you a lot of fun...';
    445 fi
     480        echo '  Building with these protocols:' $protocols
     481else
     482        echo '  Building without IM-protocol support. We wish you a lot of fun...'
     483fi
  • doc/CHANGES

    r695e392 r69cb623  
     1Version x.x:
     2- Most important change: New file format for user data (accounts, nicks and
     3  settings). Migration to the new format should happen transparently,
     4  BitlBee will read the old files and once you quit/save it will save in the
     5  new format. It is recommended to delete the old files (BitlBee doesn't do
     6  this automatically, it will just ignore them) since they won't be used
     7  anymore (and since the old file format is a security risk). Some advantages
     8  of this file format switch:
     9  * Safer format, since the identify-password is now salted before generating
     10    a checksum. This way one can't use MD5 reverse lookup databases to crack
     11    passwords. Also, the IM-account passwords are encrypted using RC4 instead
     12    of the simple obfuscation scheme which BitlBee used so far.
     13  * Easier to extend than the previous format (at least the .nicks format was
     14    horribly limited).
     15  * Nicknames for buddies are now saved per-account instead of per-protocol.
     16    So far having one buddy on multiple accounts of the same protocol was a
     17    problem because the nicks generated for the two "instances" of this buddy
     18    were very unpredictable.
     19    NOTE: This also means that "account del" removes not just the account,
     20    BUT ALSO ALL NICKNAMES! If you're changing IM accounts and don't want to
     21    lose the nicknames, you can now use "account set" to change the username
     22    and password for the existing connection.
     23  * Per-account settings (see the new "account set" command).
     24
    125Version 1.0:
    226- Removed some crashy debugging code.
  • doc/README

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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                <para>
     436                        With this option enabled, root will inform you when someone in your buddy list changes his/her "friendly name".
     437                </para>
     438        </bitlbee-setting>
     439
     440        <bitlbee-setting name="handle_unknown" type="string" scope="global">
    393441                <default>root</default>
    394442                <possible-values>root, add, add_private, add_channel, ignore</possible-values>
     
    417465        </bitlbee-setting>
    418466
    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">
     467        <bitlbee-setting name="lcnicks" type="boolean" scope="global">
     468                <default>true</default>
     469
     470                <description>
     471                        <para>
     472                                Hereby you can change whether you want all lower case nick names or leave the case as it intended by your peer.
     473                        </para>
     474                </description>
     475
     476        </bitlbee-setting>
     477
     478        <bitlbee-setting name="ops" type="string" scope="global">
     479                <default>both</default>
     480                <possible-values>both, root, user, none</possible-values>
     481
     482                <description>
     483                        <para>
     484                                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.
     485                        </para>
     486
     487                        <para>
     488                                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.
     489                        </para>
     490                </description>
     491        </bitlbee-setting>
     492
     493        <bitlbee-setting name="password" type="string" scope="both">
     494                <description>
     495                        <para>
     496                                Use this global setting to change your "NickServ" password.
     497                        </para>
     498                       
     499                        <para>
     500                                This setting is also available for all IM accounts to change the password BitlBee uses to connect to the service.
     501                        </para>
     502                       
     503                        <para>
     504                                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.
     505                        </para>
     506                </description>
     507        </bitlbee-setting>
     508       
     509        <bitlbee-setting name="port" type="integer" scope="account">
     510                <description>
     511                        <para>
     512                                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.
     513                        </para>
     514                </description>
     515        </bitlbee-setting>
     516
     517        <bitlbee-setting name="private" type="boolean" scope="global">
     518                <default>true</default>
     519
     520                <description>
     521                        <para>
     522                                If value is true, messages from users will appear in separate query windows. If false, messages from users will appear in the control channel.
     523                        </para>
     524
     525                        <para>
     526                                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.
     527                        </para>
     528                </description>
     529        </bitlbee-setting>
     530
     531        <bitlbee-setting name="query_order" type="string" scope="global">
    524532                <default>lifo</default>
    525533                <possible-values>lifo, fifo</possible-values>
     
    536544        </bitlbee-setting>
    537545
    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 
     546        <bitlbee-setting name="resource" type="string" scope="account">
     547                <default>BitlBee</default>
     548
     549                <description>
     550                        <para>
     551                                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.
     552                        </para>
     553                </description>
     554        </bitlbee-setting>
     555
     556        <bitlbee-setting name="save_on_quit" type="boolean" scope="global">
     557                <default>true</default>
     558
     559                <description>
     560                        <para>
     561                                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.
     562                        </para>
     563                </description>
     564        </bitlbee-setting>
     565
     566        <bitlbee-setting name="server" type="string" scope="account">
     567                <description>
     568                        <para>
     569                                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.
     570                        </para>
     571                </description>
     572        </bitlbee-setting>
     573
     574        <bitlbee-setting name="ssl" type="boolean" scope="account">
     575                <default>false</default>
     576
     577                <description>
     578                        <para>
     579                                Currently only available for Jabber connections. Set this to true if the server accepts SSL connections.
     580                        </para>
     581                </description>
     582        </bitlbee-setting>
     583
     584        <bitlbee-setting name="strip_html" type="boolean" scope="global">
     585                <default>true</default>
     586
     587                <description>
     588                        <para>
     589                                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.
     590                        </para>
     591                        <para>
     592                                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.
     593                        </para>
     594                </description>
     595        </bitlbee-setting>
     596
     597        <bitlbee-setting name="to_char" type="string" scope="global">
     598                <default>": "</default>
     599
     600                <description>
     601                        <para>
     602                                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>.
     603                        </para>
     604
     605                        <para>
     606                                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.
     607                        </para>
     608                </description>
     609        </bitlbee-setting>
     610
     611        <bitlbee-setting name="typing_notice" type="boolean" scope="global">
     612                <default>false</default>
     613
     614                <description>
     615                        <para>
     616                                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. ;-)
     617                        </para>
     618                </description>
     619        </bitlbee-setting>
     620
     621        <bitlbee-setting name="web_aware" type="string" scope="account">
     622                <default>false</default>
     623
     624                <description>
     625                        <para>
     626                                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.
     627                        </para>
     628
     629                        <para>
     630                                Unless you really intend to use this feature somewhere (on forums or maybe a website), it's probably better to keep this setting disabled.
     631                        </para>
     632                </description>
    547633        </bitlbee-setting>
    548634
     
    674760                                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.
    675761                        </para>
     762
     763                        <para>
     764                                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.
     765                        </para>
    676766                </description>
    677767
  • doc/user-guide/help.xsl

    r695e392 r69cb623  
    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>
  • irc.c

    r695e392 r69cb623  
    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
     
    123126        irc_connection_list = g_slist_append( irc_connection_list, irc );
    124127       
    125         set_add( irc, "away_devoice", "true",  set_eval_away_devoice );
    126         set_add( irc, "auto_connect", "true", set_eval_bool );
    127         set_add( irc, "auto_reconnect", "false", set_eval_bool );
    128         set_add( irc, "auto_reconnect_delay", "300", set_eval_int );
    129         set_add( irc, "buddy_sendbuffer", "false", set_eval_bool );
    130         set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int );
    131         set_add( irc, "charset", "iso8859-1", set_eval_charset );
    132         set_add( irc, "debug", "false", set_eval_bool );
    133         set_add( irc, "default_target", "root", NULL );
    134         set_add( irc, "display_namechanges", "false", set_eval_bool );
    135         set_add( irc, "handle_unknown", "root", NULL );
    136         set_add( irc, "lcnicks", "true", set_eval_bool );
    137         set_add( irc, "ops", "both", set_eval_ops );
    138         set_add( irc, "private", "true", set_eval_bool );
    139         set_add( irc, "query_order", "lifo", NULL );
    140         set_add( irc, "save_on_quit", "true", set_eval_bool );
    141         set_add( irc, "strip_html", "true", NULL );
    142         set_add( irc, "to_char", ": ", set_eval_to_char );
    143         set_add( irc, "typing_notice", "false", set_eval_bool );
    144         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 );
    145148       
    146149        conf_loaddefaults( irc );
     
    206209void irc_free(irc_t * irc)
    207210{
    208         account_t *account, *accounttmp;
     211        account_t *account;
    209212        user_t *user, *usertmp;
    210         nick_t *nick, *nicktmp;
    211213        help_t *helpnode, *helpnodetmp;
    212         set_t *setnode, *setnodetmp;
    213214       
    214215        log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
    215216       
    216         if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) )
     217        if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) )
    217218                if( storage_save( irc, TRUE ) != STORAGE_OK )
    218219                        irc_usermsg( irc, "Error while saving settings!" );
     
    254255                query_del(irc, irc->queries);
    255256       
    256         if (irc->accounts != NULL) {
    257                 account = irc->accounts;
    258                 while (account != NULL) {
    259                         g_free(account->user);
    260                         g_free(account->pass);
    261                         g_free(account->server);
    262                         accounttmp = account;
    263                         account = account->next;
    264                         g_free(accounttmp);
    265                 }
    266         }
     257        while (irc->accounts)
     258                account_del(irc, irc->accounts);
     259       
     260        while (irc->set)
     261                set_del(&irc->set, irc->set->key);
    267262       
    268263        if (irc->users != NULL) {
     
    289284        g_hash_table_destroy(irc->watches);
    290285       
    291         if (irc->nicks != NULL) {
    292                 nick = irc->nicks;
    293                 while (nick != NULL) {
    294                         g_free(nick->nick);
    295                         g_free(nick->handle);
    296                                        
    297                         nicktmp = nick;
    298                         nick = nick->next;
    299                         g_free(nicktmp);
    300                 }
    301         }
    302286        if (irc->help != NULL) {
    303287                helpnode = irc->help;
     
    310294                }
    311295        }
    312         if (irc->set != NULL) {
    313                 setnode = irc->set;
    314                 while (setnode != NULL) {
    315                         g_free(setnode->key);
    316                         g_free(setnode->def);
    317                         g_free(setnode->value);
    318                        
    319                         setnodetmp = setnode;
    320                         setnode = setnode->next;
    321                         g_free(setnodetmp);
    322                 }
    323         }
    324296        g_free(irc);
    325297       
     
    332304void irc_setpass (irc_t *irc, const char *pass)
    333305{
    334         if (irc->password) g_free (irc->password);
     306        g_free (irc->password);
    335307       
    336308        if (pass) {
    337309                irc->password = g_strdup (pass);
    338                 irc_usermsg (irc, "Password successfully changed");
    339310        } else {
    340311                irc->password = NULL;
     
    367338                        }
    368339                       
    369                         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 ) )
    370341                        {
    371342                                conv[IRC_MAX_LINE] = 0;
     
    587558       
    588559        strip_newlines( line );
    589         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 ) )
    590561        {
    591562                char conv[IRC_MAX_LINE+1];
     
    655626        char namelist[385] = "";
    656627        struct conversation *c = NULL;
    657         char *ops = set_getstr( irc, "ops" );
     628        char *ops = set_getstr( &irc->set, "ops" );
    658629       
    659630        /* RFCs say there is no error reply allowed on NAMES, so when the
     
    670641                        }
    671642                       
    672                         if( u->gc && !u->away && set_getint( irc, "away_devoice" ) )
     643                        if( u->gc && !u->away && set_getbool( &irc->set, "away_devoice" ) )
    673644                                strcat( namelist, "+" );
    674645                        else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ||
     
    930901{
    931902        char *nick, *s;
    932         char reason[64];
     903        char reason[128];
    933904       
    934905        if( u->gc && u->gc->flags & OPT_LOGGING_OUT )
    935906        {
    936                 if( u->gc->user->proto_opt[0][0] )
     907                if( u->gc->acc->server )
    937908                        g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
    938                                     u->gc->user->proto_opt[0] );
     909                                    u->gc->acc->server );
    939910                else if( ( s = strchr( u->gc->username, '@' ) ) )
    940911                        g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
     
    942913                else
    943914                        g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
    944                                     u->gc->prpl->name, irc->myhost );
     915                                    u->gc->acc->prpl->name, irc->myhost );
    945916               
    946917                /* proto_opt might contain garbage after the : */
     
    1018989                else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
    1019990                {
    1020                         if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 )
     991                        if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 )
    1021992                        {
    1022993                                time_t current_typing_notice = time( NULL );
     
    1024995                                if( current_typing_notice - u->last_typing_notice >= 5 )
    1025996                                {
    1026                                         u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
     997                                        u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
    1027998                                        u->last_typing_notice = current_typing_notice;
    1028999                                }
     
    10571028                }
    10581029        }
    1059         else if( c && c->gc && c->gc->prpl )
     1030        else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
    10601031        {
    10611032                return( bim_chat_msg( c->gc, c->id, s ) );
     
    10891060        if( !u || !u->gc ) return;
    10901061       
    1091         if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
     1062        if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
    10921063        {
    10931064                int delay;
     
    11161087                strcat( u->sendbuf, "\n" );
    11171088               
    1118                 delay = set_getint( irc, "buddy_sendbuffer_delay" );
     1089                delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
    11191090                if( delay <= 5 )
    11201091                        delay *= 1000;
     
    11811152                int len = strlen( irc->nick) + 3;
    11821153                prefix = g_new (char, len );
    1183                 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );
     1154                g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
    11841155                prefix[len-1] = 0;
    11851156        }
  • irc.h

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

    r695e392 r69cb623  
    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 );
  • lib/events.h

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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 );
    3343       
     
    3747        md->fd = -1;
    3848       
    39         if( strchr( acct->username, '@' ) == NULL )
     49        if( strchr( acc->user, '@' ) == NULL )
    4050        {
    4151                hide_login_progress( gc, "Invalid account name" );
     
    212222static void msn_set_info( struct gaim_connection *gc, char *info )
    213223{
    214         char buf[1024], *fn;
    215         struct msn_data *md = gc->proto_data;
    216        
    217         if( strlen( info ) > 129 )
    218         {
    219                 do_error_dialog( gc, "Maximum name length exceeded", "MSN" );
    220                 return;
    221         }
    222        
    223         fn = msn_http_encode( info );
    224        
    225         g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
    226         msn_write( gc, buf, strlen( buf ) );
    227         g_free( fn );
     224        msn_set_display_name( set_find( &gc->acc->set, "display_name" ), info );
    228225}
    229226
     
    364361}
    365362
     363static char *msn_set_display_name( set_t *set, char *value )
     364{
     365        account_t *acc = set->data;
     366        struct gaim_connection *gc = acc->gc;
     367        struct msn_data *md;
     368        char buf[1024], *fn;
     369        int i;
     370       
     371        /* Double-check. */
     372        if( gc == NULL )
     373                return NULL;
     374       
     375        md = gc->proto_data;
     376       
     377        if( strlen( value ) > 129 )
     378        {
     379                serv_got_crap( gc, "Maximum name length exceeded" );
     380                return NULL;
     381        }
     382       
     383        fn = msn_http_encode( value );
     384       
     385        g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
     386        msn_write( gc, buf, strlen( buf ) );
     387        g_free( fn );
     388       
     389        /* Returning NULL would be better, because the server still has to
     390           confirm the name change. However, it looks a bit confusing to the
     391           user. */
     392        return value;
     393}
     394
    366395void msn_init()
    367396{
    368397        struct prpl *ret = g_new0(struct prpl, 1);
     398       
    369399        ret->name = "msn";
    370400        ret->login = msn_login;
     401        ret->acc_init = msn_acc_init;
    371402        ret->close = msn_close;
    372403        ret->send_im = msn_send_im;
     
    388419        ret->rem_deny = msn_rem_deny;
    389420        ret->send_typing = msn_send_typing;
    390         ret->cmp_buddynames = g_strcasecmp;
     421        ret->handle_cmp = g_strcasecmp;
    391422
    392423        register_protocol(ret);
  • protocols/msn/ns.c

    r695e392 r69cb623  
    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/nogaim.c

    r695e392 r69cb623  
    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 */
     
    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] = "";
     
    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

    r695e392 r69cb623  
    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/oscar.c

    r695e392 r69cb623  
    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}
     
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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}
     
    411411        ret->chat_leave = byahoo_chat_leave;
    412412        ret->chat_open = byahoo_chat_open;
    413         ret->cmp_buddynames = g_strcasecmp;
     413
     414        ret->handle_cmp = g_strcasecmp;
    414415       
    415416        register_protocol(ret);
     
    427428                yd = gc->proto_data;
    428429               
    429                 if( !strcmp(gc->prpl->name, "yahoo") && yd->y2_id == id )
     430                if( strcmp( gc->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
    430431                        return( gc );
    431432        }
  • query.c

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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] );
     
    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

    r695e392 r69cb623  
    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 )
    165 {
    166         char *s = value;
    167        
    168         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 )
     173char *set_eval_int( set_t *set, char *value )
     174{
     175        char *s;
     176       
     177        for( s = value; *s; s ++ )
     178                if( !isdigit( *s ) )
     179                        return NULL;
     180       
     181        return value;
     182}
     183
     184char *set_eval_bool( set_t *set, char *value )
     185{
     186        return is_bool( value ) ? value : NULL;
     187}
     188
     189char *set_eval_to_char( set_t *set, char *value )
    185190{
    186191        char *s = g_new( char, 3 );
     
    191196                sprintf( s, "%c ", *value );
    192197       
    193         return( s );
    194 }
    195 
    196 char *set_eval_ops( irc_t *irc, set_t *set, char *value )
    197 {
     198        return s;
     199}
     200
     201char *set_eval_ops( set_t *set, char *value )
     202{
     203        irc_t *irc = set->data;
     204       
    198205        if( g_strcasecmp( value, "user" ) == 0 )
    199         {
    200206                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    201207                                                              irc->channel, "+o-o", irc->nick, irc->mynick );
    202                 return( value );
    203         }
    204208        else if( g_strcasecmp( value, "root" ) == 0 )
    205         {
    206209                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    207210                                                              irc->channel, "-o+o", irc->nick, irc->mynick );
    208                 return( value );
    209         }
    210211        else if( g_strcasecmp( value, "both" ) == 0 )
    211         {
    212212                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    213213                                                              irc->channel, "+oo", irc->nick, irc->mynick );
    214                 return( value );
    215         }
    216214        else if( g_strcasecmp( value, "none" ) == 0 )
    217         {
    218215                irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
    219216                                                              irc->channel, "-oo", irc->nick, irc->mynick );
    220                 return( value );
    221         }
    222        
    223         return( NULL );
    224 }
    225 
     217        else
     218                return NULL;
     219       
     220        return value;
     221}
     222
     223char *set_eval_charset( set_t *set, char *value )
     224{
     225        GIConv cd;
     226
     227        if ( g_strncasecmp( value, "none", 4 ) == 0 )
     228                return value;
     229
     230        cd = g_iconv_open( "UTF-8", value );
     231        if( cd == (GIConv) -1 )
     232                return NULL;
     233
     234        g_iconv_close( cd );
     235        return value;
     236}
  • set.h

    r695e392 r69cb623  
    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 );
  • storage.c

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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

    r695e392 r69cb623  
    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{
     
    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

    r695e392 r69cb623  
    4848       
    4949        b_main_init();
    50        
    5150        log_init();
    52 
    5351        nogaim_init();
    54 
     52       
     53        srand( time( NULL ) ^ getpid() );
     54       
    5555        CONF_FILE = g_strdup( CONF_FILE_DEF );
    56        
    5756        global.helpfile = g_strdup( HELP_FILE );
    58 
     57       
    5958        global.conf = conf_load( argc, argv );
    6059        if( global.conf == NULL )
    6160                return( 1 );
    62 
    63 
     61       
    6462        if( global.conf->runmode == RUNMODE_INETD )
    6563        {
     
    8987        if( i != 0 )
    9088                return( i );
    91 
     89       
    9290        global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );
    9391        if ( global.storage == NULL) {
  • user.c

    r695e392 r69cb623  
    6767       
    6868        u->user = u->realname = u->host = u->nick = g_strdup( nick );
    69         u->is_private = set_getint( irc, "private" );
     69        u->is_private = set_getbool( &irc->set, "private" );
    7070       
    7171        key = g_strdup( nick );
     
    143143user_t *user_findhandle( struct gaim_connection *gc, char *handle )
    144144{
    145         user_t *u = gc->irc->users;
    146        
    147         while( u )
    148         {
    149                 if( u->gc == gc && u->handle && gc->prpl->cmp_buddynames ( u->handle, handle ) == 0 )
    150                         break;
    151                 u = u->next;
    152         }
    153        
    154         return( u );
     145        user_t *u;
     146        char *nick;
     147       
     148        /* First, let's try a hash lookup. If it works, it's probably faster. */
     149        if( ( nick = g_hash_table_lookup( gc->acc->nicks, handle ) ) &&
     150            ( u = user_find( gc->irc, nick ) ) &&
     151            ( gc->acc->prpl->handle_cmp( handle, u->handle ) == 0 ) )
     152                return u;
     153       
     154        /* However, it doesn't always work, so in that case we'll have to dig
     155           through the whole userlist. :-( */
     156        for( u = gc->irc->users; u; u = u->next )
     157                if( u->gc == gc && u->handle && gc->acc->prpl->handle_cmp( u->handle, handle ) == 0 )
     158                        return u;
     159       
     160        return NULL;
    155161}
    156162
Note: See TracChangeset for help on using the changeset viewer.