Changes in / [823de9d:673a54c]


Ignore:
Files:
3 added
39 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r823de9d r673a54c  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o
     12objects = account.o bitlbee.o chat.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o
    1313headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h otr.h query.h set.h sock.h storage.h user.h lib/events.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h
    1414subdirs = lib protocols
  • account.c

    r823de9d r673a54c  
    190190{
    191191        account_t *a, *l = NULL;
     192        struct chat *c, *nc;
    192193       
    193194        if( acc->ic )
     
    202203                        else
    203204                                irc->accounts = a->next;
     205                       
     206                        for( c = irc->chatrooms; c; c = nc )
     207                        {
     208                                nc = c->next;
     209                                if( acc == c->acc )
     210                                        chat_del( irc, c );
     211                        }
    204212                       
    205213                        while( a->set )
  • bitlbee.h

    r823de9d r673a54c  
    132132#include "account.h"
    133133#include "nick.h"
     134#include "chat.h"
    134135#include "conf.h"
    135136#include "log.h"
  • conf.c

    r823de9d r673a54c  
    7979        }
    8080       
    81         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hu:" ) ) >= 0 )
     81        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
    8282        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
    8383        {
     
    314314                        else
    315315                        {
    316                                 fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
     316                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file (line %d).\n", ini->key, ini->line );
    317317                                return 0;
    318318                                /* For now just ignore unknown keys... */
     
    321321                else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
    322322                {
    323                         fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
    324                                          "BitlBee configuration must be put in a [settings] section!\n", ini->section );
     323                        fprintf( stderr, "Error: Unknown section [%s] in configuration file (line %d). "
     324                                         "BitlBee configuration must be put in a [settings] section!\n", ini->section, ini->line );
    325325                        return 0;
    326326                }
  • debian/bitlbee.init

    r823de9d r673a54c  
    3232fi
    3333
    34 [ "$BITLBEE_DISABLED" = "1" ] && exit 0
    35 
    3634
    3735#
     
    4139        # Make sure BitlBee can actually write its PID...
    4240        touch /var/run/bitlbee.pid
    43         chown bitlbee /var/run/bitlbee.pid
     41        chown bitlbee: /var/run/bitlbee.pid
    4442       
    45         start-stop-daemon --start --quiet --pidfile $PIDFILE \
     43        # Clean up after the bug between 1.2-5 and 1.2.1-2 where BitlBee ran
     44        # as root. (#494656 and #495877) Fixing this in the postinst script
     45        # is not enough since the user will restart his BitlBee after up-
     46        # grading the package, and the BitlBee running as root will then
     47        # save its settings, re-setting ownership of the file to root.
     48        # TODO: Remove this after a few revisions.
     49        find /var/lib/bitlbee -uid 0 -name '*.xml' -exec chown bitlbee: {} \;
     50
     51        start-stop-daemon --start --quiet \
    4652                --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS
    4753}
     
    5864case "$1" in
    5965  start)
     66        [ "$BITLBEE_DISABLED" = "1" ] && exit 0
     67
    6068        echo -n "Starting $DESC: $NAME"
    6169        d_start
  • debian/changelog

    r823de9d r673a54c  
    1 bitlbee (1.2-6) UNRELEASED; urgency=low
    2 
    3   * Add Homepage and Vcs-Bzr fields.
    4 
    5  -- Jelmer Vernooij <jelmer@samba.org>  Sun, 11 May 2008 14:18:16 +0200
     1bitlbee (1.2.2-1) unstable; urgency=critical
     2
     3  * New upstream version.
     4  * Fixes a security issue (account hijacking), hence the high priority.
     5  * Using a patch to set the User setting in bitlbee.conf properly to keep
     6    upstream and Debian properly separated in my bzr tree.
     7
     8 -- Wilmer van der Gaast <wilmer@gaast.net>  Wed, 27 Aug 2008 23:59:50 +0100
     9
     10bitlbee (1.2.1-3) unstable; urgency=high
     11
     12  * chown /var/lib/bitlbee/*.xml to bitlbee:bitlbee to clean up after
     13    1.2-5 and the bugfix in 1.2.1-2. (Closes: #495877)
     14  * Moved BITLBEE_DISABLED check to only check when trying to *start*
     15    the daemon. (Closes: #488611)
     16
     17 -- Wilmer van der Gaast <wilmer@gaast.net>  Sat, 23 Aug 2008 18:53:54 +0100
     18
     19bitlbee (1.2.1-2) unstable; urgency=low
     20
     21  * Properly set the User= line to something sensible so BitlBee won't
     22    run as root anymore. 1.2-5 was a bad upload. :-( (Closes: #494656)
     23
     24 -- Wilmer van der Gaast <wilmer@gaast.net>  Tue, 12 Aug 2008 00:36:03 +0100
     25
     26bitlbee (1.2.1-1.1) unstable; urgency=low
     27
     28  * Non-Maintainer Upload
     29  * Use invoke-rc.d as per policy. (Closes: #492637) [Thanks to Matt
     30    Kraai]
     31
     32 -- Don Armstrong <don@debian.org>  Wed, 06 Aug 2008 06:57:18 -0700
     33
     34bitlbee (1.2.1-1) unstable; urgency=low
     35
     36  * New upstream release.
     37  * Add Homepage and Vcs-Bzr fields. (From Jelmer.)
     38
     39 -- Wilmer van der Gaast <wilmer@gaast.net>  Thu, 26 Jun 2008 00:07:50 +0100
    640
    741bitlbee (1.2-5) unstable; urgency=low
  • debian/postinst

    r823de9d r673a54c  
    6464fi
    6565
     66if ! grep -qi '^User *= *' /etc/bitlbee/bitlbee.conf; then
     67        echo 'Updating configuration file, enabling User-setting...'
     68        if ! sed -i -e 's/# *User *= *.*/User = bitlbee/i' /etc/bitlbee/bitlbee.conf; then
     69                echo 'Failed! BitlBee may run as root now, please check your configs.'
     70        fi
     71fi
     72
    6673if [ -n "$2" -a "$BITLBEE_UPGRADE_DONT_RESTART" != "1" ]; then
    67         /etc/init.d/bitlbee restart
     74        if which invoke-rc.d >/dev/null 2>&1; then
     75                invoke-rc.d bitlbee restart
     76        else
     77                /etc/init.d/bitlbee restart
     78        fi
    6879fi
    6980
    7081## If we're upgrading, we'll probably skip this next part
    71 if [ -d $CONFDIR ] && chown -R bitlbee $CONFDIR; then
     82if [ -d $CONFDIR ] && chown -R bitlbee: $CONFDIR; then
    7283        echo 'BitlBee (probably) already installed, skipping user/configdir installation'
    7384        exit 0
     
    91102
    92103if [ -z "$2" ]; then
    93         /etc/init.d/bitlbee start
     104        if which invoke-rc.d >/dev/null 2>&1; then
     105                invoke-rc.d bitlbee start
     106        else
     107                /etc/init.d/bitlbee start
     108        fi
    94109fi
  • debian/prerm

    r823de9d r673a54c  
    1010        fi
    1111else
    12         /etc/init.d/bitlbee stop || exit 0
     12        if which invoke-rc.d >/dev/null 2>&1; then
     13                invoke-rc.d bitblee stop || exit 0
     14        else
     15                /etc/init.d/bitlbee stop || exit 0
     16        fi
    1317fi
  • debian/rules

    r823de9d r673a54c  
    5555        cp utils/* debian/bitlbee/usr/share/doc/bitlbee/examples/
    5656        cp debian/bitlbee.init debian/bitlbee/etc/init.d/bitlbee
     57        patch -p0 < debian/patches/bitlbee.conf.diff
    5758        cd debian/bitlbee/usr/share/; \
    5859                gzip -9 doc/bitlbee/changelog.Debian doc/bitlbee/changelog doc/bitlbee/user-guide.txt \
  • doc/user-guide/Makefile

    r823de9d r673a54c  
    1313
    1414%.html: %.db.xml
    15         xsltproc --output $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $<
     15        xsltproc --output $@ http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $<
    1616
    1717%.pdf: %.db.xml
  • doc/user-guide/commands.xml

    r823de9d r673a54c  
    125125                        <description>
    126126                                <para>
    127                                         This command gives you a list of all the accounts known by BitlBee, including the numbers you'll need for most account commands.
     127                                        This command gives you a list of all the accounts known by BitlBee.
    128128                                </para>
    129129                        </description>
     
    138138                        <description>
    139139                                <para>
    140                                         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>.
    141                                 </para>
    142                                
    143                                 <para>
    144                                         For more infomation about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>. For details about the syntax of this command, see <emphasis>help set</emphasis>.
     140                                        This command 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>.
     141                                </para>
     142                               
     143                                <para>
     144                                        For more infomation about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
    145145                                </para>
    146146                               
    147147                                <para>
    148148                                        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.
     149                                </para>
     150                        </description>
     151                </bitlbee-command>
     152        </bitlbee-command>
     153
     154        <bitlbee-command name="chat">
     155                <short-description>Chatroom list maintenance</short-description>
     156                <syntax>chat &lt;action&gt; [&lt;arguments&gt;]</syntax>
     157
     158                <description>
     159
     160                        <para>
     161                                Available actions: add, del, list, with and set. See <emphasis>help chat &lt;action&gt;</emphasis> for more information.
     162                        </para>
     163
     164                </description>
     165
     166                <bitlbee-command name="add">
     167                        <syntax>chat add &lt;account&gt; &lt;room&gt; [&lt;channel&gt;]</syntax>
     168
     169                        <description>
     170                                <para>
     171                                        Add a chatroom to the list of chatrooms you're interested in. BitlBee needs this list to map room names to a proper IRC channel name.
     172                                </para>
     173
     174                                <para>
     175                                        After adding a room to your list, you can simply use the IRC /join command to enter the room. Also, you can tell BitlBee to automatically join the room when you log in. (See <emphasis>chat set</emphasis>)
     176                                </para>
     177                        </description>
     178
     179                </bitlbee-command>
     180
     181                <bitlbee-command name="del">
     182                        <syntax>chat del &lt;chat id&gt;</syntax>
     183
     184                        <description>
     185                                <para>
     186                                        This commands deletes an chatroom from your list.
     187                                </para>
     188
     189                                <para>
     190                                        The room ID can be a number (see <emphasis>chat list</emphasis>), or (part of) the name of the room/channel.
     191                                </para>
     192                        </description>
     193                </bitlbee-command>
     194
     195                <bitlbee-command name="list">
     196                        <syntax>chat list</syntax>
     197
     198                        <description>
     199                                <para>
     200                                        This command gives you a list of all the chatrooms known by BitlBee.
     201                                </para>
     202                        </description>
     203                </bitlbee-command>
     204
     205                <bitlbee-command name="with">
     206                        <syntax>chat with &lt;nickname&gt;</syntax>
     207
     208                        <description>
     209                                <para>
     210                                        While most <emphasis>chat</emphasis> subcommands are about named chatrooms, this command can be used to open an unnamed groupchat with one or more persons. This command is what <emphasis>/join #nickname</emphasis> used to do in older BitlBee versions.
     211                                </para>
     212                        </description>
     213                </bitlbee-command>
     214
     215                <bitlbee-command name="set">
     216                        <syntax>chat set &lt;chat id&gt;</syntax>
     217                        <syntax>chat set &lt;chat id&gt;/&lt;setting&gt;</syntax>
     218                        <syntax>chat set &lt;chat id&gt;/&lt;setting&gt; &lt;value&gt;</syntax>
     219                        <syntax>chat set -del &lt;chat id&gt;/&lt;setting&gt;</syntax>
     220
     221                        <description>
     222                                <para>
     223                                        This command can be used to change various settings for chatrooms.
     224                                </para>
     225                               
     226                                <para>
     227                                        For more infomation about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
     228                                </para>
     229                               
     230                                <para>
     231                                        The room ID can be a number (see <emphasis>chat list</emphasis>), or (part of) the name of the room/channel.
    149232                                </para>
    150233                        </description>
     
    452535        </bitlbee-setting>
    453536
     537        <bitlbee-setting name="auto_join" type="boolean" scope="chat">
     538                <default>false</default>
     539
     540                <description>
     541                        <para>
     542                                With this option enabled, BitlBee will automatically join this chatroom when you log in.
     543                        </para>
     544                </description>
     545        </bitlbee-setting>
     546
    454547        <bitlbee-setting name="auto_reconnect" type="boolean" scope="both">
    455548                <default>false</default>
     
    712805        </bitlbee-setting>
    713806
     807        <bitlbee-setting name="nick" type="string" scope="chat">
     808
     809                <description>
     810                        <para>
     811                                You can use this option to set your nickname in a chatroom. You won't see this nickname yourself, but other people in the room will. By default, BitlBee will use your username as the chatroom nickname.
     812                        </para>
     813                </description>
     814        </bitlbee-setting>
     815
    714816        <bitlbee-setting name="password" type="string" scope="both">
    715817                <description>
     
    791893        <bitlbee-setting name="resource_select" type="string" scope="account">
    792894                <default>priority</default>
    793                 <possible-values>priority, time</possible-values>
     895                <possible-values>priority, activity</possible-values>
    794896
    795897                <description>
     
    799901
    800902                        <para>
    801                                 Normally it's set to <emphasis>priority</emphasis> which means messages will always be delivered to the buddy's resource with the highest priority. If the setting is set to <emphasis>time</emphasis>, messages will be delivered to the resource that was last used to send you a message (or the resource that most recently connected).
     903                                Normally it's set to <emphasis>priority</emphasis> which means messages will always be delivered to the buddy's resource with the highest priority. If the setting is set to <emphasis>activity</emphasis>, messages will be delivered to the resource that was last used to send you a message (or the resource that most recently connected).
    802904                        </para>
    803905                </description>
     
    10811183
    10821184        </bitlbee-command>
    1083 
    1084         <bitlbee-command name="join_chat">
    1085                 <short-description>Join a named groupchat/conference room</short-description>
    1086                 <syntax>join_chat &lt;connection&gt; &lt;room name&gt; [&lt;channel name&gt;] [&lt;room nickname&gt;] [&lt;password&gt;]</syntax>
    1087 
    1088                 <description>
    1089                         <para>
    1090                                 On most IM-networks groupchats can be started using the /join command. (<emphasis>/join #foo</emphasis> to start a chatroom with you and <emphasis>foo</emphasis>) This doesn't work with names groupchats though (which exist on Jabber networks and AIM, for example), instead you can use this command.
    1091                         </para>
    1092 
    1093                         <para>
    1094                                 The first two arguments are required. <emphasis>room name</emphasis> is the name of the chatroom on the IM-network. <emphasis>channel name</emphasis> is the IRC channel name BitlBee should map this to. <emphasis>room nickname</emphasis> is the nickname you want to have in this channel. If you don't give these options, BitlBee will do the right guesses.
    1095                         </para>
    1096 
    1097                         <para>
    1098                                 The following command will join you to the chatroom called <emphasis>bitlbee@conference.bitlbee.org</emphasis>. The channel will be called <emphasis>&amp;bitlbee-help</emphasis> because <emphasis>&amp;bitlbee</emphasis> will already be in use. Your nickname will be <emphasis>help-me</emphasis>.
    1099                         </para>
    1100                 </description>
    1101 
    1102                 <ircexample>
    1103                         <ircline nick="wilmer">join_chat jabber bitlbee@conference.bitlbee.org &amp;bitlbee-help help-me</ircline>
    1104                 </ircexample>
    1105 
    1106         </bitlbee-command>
    11071185</chapter>
  • doc/user-guide/help.xml

    r823de9d r673a54c  
    1 <?xml version="1.0" encoding="iso-8859-1"?>
     1<?xml version="1.0" encoding="utf-8"?>
    22<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
    33
  • doc/user-guide/misc.xml

    r823de9d r673a54c  
    6969
    7070<para>
    71 If you want to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just join the channel <emphasis>#lisa_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and lisa_msn in it.
     71To open a groupchat, use the <emphasis>chat with</emphasis> command. For example,  to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just type <emphasis>chat with lisa_msn</emphasis>. BitlBee will create a new virtual channel with root, you and lisa_msn in it.
    7272</para>
    7373
    7474<para>
    75 Of course a channel with only two people isn't really exciting yet. So the next step is to invite some other people to the channel. For this, you can use the <emphasis>/invite</emphasis> command of your IRC client. Please do keep in mind that all the people have to be on the same network and contact list! You can't invite Yahoo! buddies into an MSN groupchat.
     75Then, just use the ordinary IRC <emphasis>/invite</emphasis> command to invite more people. Please do keep in mind that all the people have to be on the same network and contact list! You can't invite Yahoo! buddies into an MSN groupchat.
    7676</para>
    7777
    7878<para>
    79 Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>join_chat</emphasis> command to join them. See <emphasis>help join_chat</emphasis> for more information.
     79Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>chat add</emphasis> command to join them. See <emphasis>help chat_add</emphasis> for more information.
    8080</para>
    8181
  • doc/user-guide/user-guide.xml

    r823de9d r673a54c  
    1 <?xml version="1.0" encoding="iso-8859-1"?>
     1<?xml version="1.0" encoding="utf-8"?>
    22<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
    33
  • irc.c

    r823de9d r673a54c  
    146146        irc_connection_list = g_slist_append( irc_connection_list, irc );
    147147
     148       
    148149        s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
    149150        s = set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc );
     
    418419                        }
    419420                       
    420                         if( lines[i] )
    421                         {
    422                                 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    423                                         continue;
     421                        if( lines[i] && ( cmd = irc_parse_line( lines[i] ) ) )
     422                        {
    424423                                irc_exec( irc, cmd );
    425424                                g_free( cmd );
     
    496495        if( line[0] == ':' )
    497496        {
    498                 for( i = 0; line[i] != ' '; i ++ );
     497                for( i = 0; line[i] && line[i] != ' '; i ++ );
    499498                line = line + i;
    500499        }
     
    821820        irc_reply( irc,   3, ":%s", IRCD_INFO );
    822821        irc_reply( irc,   4, "%s %s %s %s", irc->myhost, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES );
    823         irc_reply( irc,   5, "PREFIX=(ohv)@%%+ CHANTYPES=#& CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server", CMODES, MAX_NICK_LENGTH - 1 );
     822        irc_reply( irc,   5, "PREFIX=(ohv)@%%+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee "
     823                             "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server",
     824                             CTYPES, CMODES, MAX_NICK_LENGTH - 1 );
    824825        irc_motd( irc );
    825826        irc->umode[0] = '\0';
     
    10851086        user_t *u = NULL;
    10861087       
    1087         if( *nick == '#' || *nick == '&' )
     1088        if( strchr( CTYPES, *nick ) )
    10881089        {
    10891090                if( !( c = irc_chat_by_channel( irc, nick ) ) )
  • irc.h

    r823de9d r673a54c  
    4040#define CMODE "t"
    4141#define UMODE "s"
     42#define CTYPES "&#"
    4243
    4344typedef enum
     
    4950        USTATUS_SHUTDOWN = 8
    5051} irc_status_t;
    51 
    52 typedef struct channel
    53 {
    54         char *name;
    55 } channel_t;
    5652
    5753typedef struct irc
     
    8985        struct query *queries;
    9086        struct account *accounts;
     87        struct chat *chatrooms;
    9188       
    9289        struct __USER *users;
     
    104101
    105102#include "user.h"
    106 // #include "nick.h"
    107103
    108104extern GSList *irc_connection_list;
  • irc_commands.c

    r823de9d r673a54c  
    125125static void irc_cmd_mode( irc_t *irc, char **cmd )
    126126{
    127         if( *cmd[1] == '#' || *cmd[1] == '&' )
     127        if( strchr( CTYPES, *cmd[1] ) )
    128128        {
    129129                if( cmd[2] )
     
    193193        else if( cmd[1] )
    194194        {
    195                 if( ( cmd[1][0] == '#' || cmd[1][0] == '&' ) && cmd[1][1] )
    196                 {
    197                         user_t *u = user_find( irc, cmd[1] + 1 );
    198                        
    199                         if( u && u->ic && u->ic->acc->prpl->chat_with )
    200                         {
    201                                 irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] );
    202                                
    203                                 if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) )
    204                                 {
    205                                         irc_usermsg( irc, "Could not open a groupchat with %s.", u->nick );
    206                                 }
    207                         }
    208                         else if( u )
    209                         {
    210                                 irc_reply( irc, 403, "%s :Groupchats are not possible with %s", cmd[1], cmd[1]+1 );
    211                         }
    212                         else
    213                         {
    214                                 irc_reply( irc, 403, "%s :No such nick", cmd[1] );
    215                         }
    216                 }
     195                struct chat *c;
     196               
     197                if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 )
     198                        irc_reply( irc, 479, "%s :Invalid channel name", cmd[1] );
     199                else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic )
     200                        chat_join( irc, c, cmd[2] );
    217201                else
    218                 {
    219202                        irc_reply( irc, 403, "%s :No such channel", cmd[1] );
    220                 }
    221203        }
    222204}
  • lib/events_libevent.c

    r823de9d r673a54c  
    3737
    3838static void b_main_restart();
    39 static guint id_next = 1;
     39static guint id_next = 1; /* Next ID to be allocated to an event handler. */
     40static guint id_cur = 0; /* Event ID that we're currently handling. */
     41static guint id_dead; /* Set to 1 if b_event_remove removes id_cur. */
    4042static GHashTable *id_hash;
    41 static int quitting = 0;
     43static int quitting = 0; /* Prepare to quit, stop handling events. */
    4244
    4345/* Since libevent doesn't handle two event handlers for one fd-condition
     
    119121        struct b_event_data *b_ev = data;
    120122        b_input_condition cond = 0;
    121         int id;
     123        gboolean st;
    122124       
    123125        if( fd >= 0 )
     
    133135        /* Since the called function might cancel this handler already
    134136           (which free()s b_ev), we have to remember the ID here. */
    135         id = b_ev->id;
     137        id_cur = b_ev->id;
     138        id_dead = 0;
    136139       
    137140        if( quitting )
    138141        {
    139                 b_event_remove( id );
     142                b_event_remove( id_cur );
    140143                return;
    141144        }
    142145       
    143         if( !b_ev->function( b_ev->data, fd, cond ) )
     146        st = b_ev->function( b_ev->data, fd, cond );
     147        if( id_dead )
     148        {
     149                /* This event was killed already, don't touch it! */
     150                return;
     151        }
     152        else if( !st )
    144153        {
    145154                event_debug( "Handler returned FALSE: " );
    146                 b_event_remove( id );
     155                b_event_remove( id_cur );
    147156        }
    148157        else if( fd == -1 )
    149158        {
     159                /* fd == -1 means it was a timer. These can't be auto-repeated
     160                   so it has to be recreated every time. */
    150161                struct timeval tv;
    151162               
     
    236247        if( b_ev )
    237248        {
     249                if( id == id_cur )
     250                        id_dead = TRUE;
     251               
    238252                g_hash_table_remove( id_hash, &b_ev->id );
    239253                if( b_ev->evinfo.ev_fd >= 0 )
  • lib/http_client.c

    r823de9d r673a54c  
    5959        if( error )
    6060        {
    61                 g_free( req );
    62                 return( NULL );
     61                http_free( req );
     62                return NULL;
    6363        }
    6464       
     
    160160       
    161161        req->func( req );
    162        
    163         g_free( req->request );
    164         g_free( req );
    165        
     162        http_free( req );
    166163        return FALSE;
    167164}
     
    444441       
    445442        req->func( req );
    446        
     443        http_free( req );
     444        return FALSE;
     445}
     446
     447void http_free( struct http_request *req )
     448{
    447449        g_free( req->request );
    448450        g_free( req->reply_headers );
    449451        g_free( req->status_string );
    450452        g_free( req );
    451        
    452         return FALSE;
    453 }
     453}
     454
  • lib/http_client.h

    r823de9d r673a54c  
    8181void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data );
    8282void *http_dorequest_url( char *url_string, http_input_function func, gpointer data );
     83
     84void http_free( struct http_request *req );
  • lib/ini.c

    r823de9d r673a54c  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2005 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2008 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2828ini_t *ini_open( char *file )
    2929{
    30         ini_t *ini = g_new0( ini_t, 1 );
     30        int fd;
     31        ini_t *ini = NULL;
     32        struct stat fi;
    3133       
    32         if( ( ini->fp = fopen( file, "r" ) ) == NULL )
     34        if( ( fd = open( file, O_RDONLY ) ) != -1 &&
     35            fstat( fd, &fi ) == 0 &&
     36            fi.st_size <= 16384 &&
     37            ( ini = g_malloc( sizeof( ini_t ) + fi.st_size + 1 ) ) &&
     38            read( fd, ini->file, fi.st_size ) == fi.st_size )
    3339        {
    34                 g_free( ini );
    35                 return( NULL );
     40                memset( ini, 0, sizeof( ini_t ) );
     41                ini->size = fi.st_size;
     42                ini->file[ini->size] = 0;
     43                ini->cur = ini->file;
     44                ini->c_section = "";
     45                return ini;
    3646        }
    3747       
    38         return( ini );
     48        g_free( ini );
     49        if( fd >= 0 )
     50                close( fd );
     51
     52        return NULL;
     53}
     54
     55/* Strips leading and trailing whitespace and returns a pointer to the first
     56   non-ws character of the given string. */
     57static char *ini_strip_whitespace( char *in )
     58{
     59        char *e;
     60
     61        while( isspace( *in ) )
     62                in++;
     63
     64        e = in + strlen( in ) - 1;
     65        while( e > in && isspace( *e ) )
     66                e--;
     67        e[1] = 0;
     68       
     69        return in;
    3970}
    4071
    4172int ini_read( ini_t *file )
    4273{
    43         char key[MAX_STRING], s[MAX_STRING], *t;
    44         int i;
     74        char *s;
    4575       
    46         while( !feof( file->fp ) )
     76        while( file->cur && file->cur < file->file + file->size )
    4777        {
    48                 *s = 0;
    49                 fscanf( file->fp, "%127[^\n#]s", s );
    50                 fscanf( file->fp, "%*[^\n]s" );
    51                 fgetc( file->fp );              /* Skip newline         */
    52                 file->line ++;
    53                 if( strchr( s, '=' ) )
     78                char *e, *next;
     79               
     80                file->line++;
     81
     82                /* Find the end of line */
     83                if( ( e = strchr( file->cur, '\n' ) ) != NULL )
    5484                {
    55                         sscanf( s, "%[^ =]s", key );
    56                         if( ( t = strchr( key, '.' ) ) )
     85                        *e = 0;
     86                        next = e + 1;
     87                }
     88                else
     89                {
     90                        /* No more lines. */
     91                        e = file->cur + strlen( file->cur );
     92                        next = NULL;
     93                }
     94               
     95                /* Comment? */
     96                if( ( s = strchr( file->cur, '#' ) ) != NULL )
     97                        *s = 0;
     98               
     99                file->cur = ini_strip_whitespace( file->cur );
     100               
     101                if( *file->cur == '[' )
     102                {
     103                        file->cur++;
     104                        if( ( s = strchr( file->cur, ']' ) ) != NULL )
    57105                        {
    58                                 *t = 0;
    59                                 strcpy( file->section, key );
    60                                 t ++;
     106                                *s = 0;
     107                                file->c_section = file->cur;
     108                        }
     109                }
     110                else if( ( s = strchr( file->cur, '=' ) ) != NULL )
     111                {
     112                        *s = 0;
     113                        file->key = ini_strip_whitespace( file->cur );
     114                        file->value = ini_strip_whitespace( s + 1 );
     115                       
     116                        if( ( s = strchr( file->key, '.' ) ) != NULL )
     117                        {
     118                                *s = 0;
     119                                file->section = file->key;
     120                                file->key = s + 1;
    61121                        }
    62122                        else
    63123                        {
    64                                 strcpy( file->section, file->c_section );
    65                                 t = key;
     124                                file->section = file->c_section;
    66125                        }
    67                         sscanf( t, "%s", file->key );
    68                         t = strchr( s, '=' ) + 1;
    69                         for( i = 0; t[i] == ' '; i ++ );
    70                         strcpy( file->value, &t[i] );
    71                         for( i = strlen( file->value ) - 1; file->value[i] == 32; i -- )
    72                                 file->value[i] = 0;
    73126                       
    74                         return( 1 );
     127                        file->cur = next;
     128                        return 1;
    75129                }
    76                 else if( ( t = strchr( s, '[' ) ) )
    77                 {
    78                         strcpy( file->c_section, t + 1 );
    79                         t = strchr( file->c_section, ']' );
    80                         *t = 0;
    81                 }
     130                /* else: noise/comment/etc, let's just ignore it. */
     131
     132                file->cur = next;
    82133        }
    83         return( 0 );
     134       
     135        return 0;
    84136}
    85137
    86138void ini_close( ini_t *file )
    87139{
    88         fclose( file->fp );
    89140        g_free( file );
    90141}
  • lib/ini.h

    r823de9d r673a54c  
    2929typedef struct
    3030{
    31         FILE *fp;
    3231        int line;
    33         char c_section[MAX_STRING];
    34         char section[MAX_STRING];
    35         char key[MAX_STRING];
    36         char value[MAX_STRING];
     32        char *c_section;
     33        char *section;
     34        char *key;
     35        char *value;
     36        int size;
     37        char *cur, *tok;
     38        char file[];
    3739} ini_t;
    3840
  • lib/proxy.c

    r823de9d r673a54c  
    558558                return proxy_connect_socks5(host, port, phb);
    559559       
    560         if (phb->host) g_free(phb);
    561560        g_free(phb);
    562561        return -1;
  • lib/xmltree.c

    r823de9d r673a54c  
    472472}
    473473
    474 struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children )
     474struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children )
    475475{
    476476        struct xt_node *node, *c;
  • lib/xmltree.h

    r823de9d r673a54c  
    9090char *xt_find_attr( struct xt_node *node, const char *key );
    9191
    92 struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children );
     92struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children );
    9393void xt_add_child( struct xt_node *parent, struct xt_node *child );
    9494void xt_add_attr( struct xt_node *node, const char *key, const char *value );
  • protocols/jabber/conference.c

    r823de9d r673a54c  
    2626static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    2727
    28 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password )
     28struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password )
    2929{
    3030        struct jabber_chat *jc;
     
    3636        node = xt_new_node( "x", NULL, NULL );
    3737        xt_add_attr( node, "xmlns", XMLNS_MUC );
    38         node = jabber_make_packet( "presence", NULL, roomjid, node );
    3938        if( password )
    4039                xt_add_child( node, xt_new_node( "password", password, NULL ) );
     40        node = jabber_make_packet( "presence", NULL, roomjid, node );
    4141        jabber_cache_add( ic, node, jabber_chat_join_failed );
    4242       
  • protocols/jabber/jabber.c

    r823de9d r673a54c  
    425425}
    426426
    427 static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password )
     427static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password )
    428428{
    429429        if( strchr( room, '@' ) == NULL )
  • protocols/jabber/jabber.h

    r823de9d r673a54c  
    240240
    241241/* conference.c */
    242 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
     242struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password );
    243243struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
    244244void jabber_chat_free( struct groupchat *c );
  • protocols/jabber/presence.c

    r823de9d r673a54c  
    4949                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
    5050                {
    51                         if( set_getbool( &ic->irc->set, "debug" ) )
    52                                 imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
     51                        /*
     52                        imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
     53                        */
    5354                        return XT_HANDLED;
    5455                }
     
    106107                if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
    107108                {
    108                         if( set_getbool( &ic->irc->set, "debug" ) )
    109                                 imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
     109                        /*
     110                        imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
     111                        */
    110112                        return XT_HANDLED;
    111113                }
  • protocols/nogaim.c

    r823de9d r673a54c  
    249249void imcb_connected( struct im_connection *ic )
    250250{
     251        irc_t *irc = ic->irc;
     252        struct chat *c;
    251253        user_t *u;
    252254       
     
    271273           exponential backoff timer. */
    272274        ic->acc->auto_reconnect_delay = 0;
     275       
     276        for( c = irc->chatrooms; c; c = c->next )
     277        {
     278                if( c->acc != ic->acc )
     279                        continue;
     280               
     281                if( set_getbool( &c->set, "auto_join" ) )
     282                        chat_join( irc, c, NULL );
     283        }
    273284}
    274285
     
    309320        ic->acc->prpl->logout( ic );
    310321        b_event_remove( ic->inpa );
     322       
     323        g_free( ic->away );
     324        ic->away = NULL;
    311325       
    312326        u = irc->users;
     
    716730}
    717731
    718 struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle )
     732struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
    719733{
    720734        struct groupchat *c;
  • protocols/nogaim.h

    r823de9d r673a54c  
    213213         * not implement this. */
    214214        struct groupchat *
    215              (* chat_join)      (struct im_connection *, char *room, char *nick, char *password);
     215             (* chat_join)      (struct im_connection *, const char *room, const char *nick, const char *password);
    216216        /* Change the topic, if supported. Note that BitlBee expects the IM
    217217           server to confirm the topic change with a regular topic change
     
    243243 * the account_t parameter. */
    244244G_MODULE_EXPORT struct im_connection *imcb_new( account_t *acc );
    245 G_MODULE_EXPORT void imcb_free( struct im_connection *ic );
     245G_MODULE_EXPORT void imc_free( struct im_connection *ic );
    246246/* Once you're connected, you should call this function, so that the user will
    247247 * see the success. */
     
    294294 *   the user her/himself. At that point the group chat will be visible to the
    295295 *   user, too. */
    296 G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle );
     296G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle );
    297297G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle );
    298298/* To remove a handle from a group chat. Reason can be NULL. */
  • protocols/oscar/oscar.c

    r823de9d r673a54c  
    9191        GSList *oscar_chats;
    9292
    93         gboolean killme;
     93        gboolean killme, no_reconnect;
    9494        gboolean icq;
    9595        GSList *evilhack;
     
    181181static int gaim_parse_auth_resp  (aim_session_t *, aim_frame_t *, ...);
    182182static int gaim_parse_login      (aim_session_t *, aim_frame_t *, ...);
     183static int gaim_parse_logout     (aim_session_t *, aim_frame_t *, ...);
    183184static int gaim_handle_redirect  (aim_session_t *, aim_frame_t *, ...);
    184185static int gaim_parse_oncoming   (aim_session_t *, aim_frame_t *, ...);
     
    294295                        aim_rxdispatch(odata->sess);
    295296                               if (odata->killme)
    296                                        imc_logout(ic, TRUE);
     297                                       imc_logout(ic, !odata->no_reconnect);
    297298                } else {
    298299                        if ((conn->type == AIM_CONN_TYPE_BOS) ||
     
    520521                case 0x18:
    521522                        /* connecting too frequently */
     523                        od->no_reconnect = TRUE;
    522524                        imcb_error(ic, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
    523525                        break;
     
    572574        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parseaiminfo, 0);
    573575        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parsemtn, 0);
     576        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_parse_logout, 0);
    574577
    575578        ((struct oscar_data *)ic->proto_data)->conn = bosconn;
     
    747750
    748751        aim_send_login(sess, fr->conn, ic->acc->user, ic->acc->pass, &info, key);
     752
     753        return 1;
     754}
     755
     756static int gaim_parse_logout(aim_session_t *sess, aim_frame_t *fr, ...) {
     757        struct im_connection *ic = sess->aux_data;
     758        struct oscar_data *odata = ic->proto_data;
     759        int code;
     760        va_list ap;
     761
     762        va_start(ap, fr);
     763        code = va_arg(ap, int);
     764        va_end(ap);
     765       
     766        imcb_error( ic, "Connection aborted by server: %s", code == 1 ?
     767                        "someone else logged in with your account" :
     768                        "unknown reason" );
     769       
     770        /* Tell BitlBee to disable auto_reconnect if code == 1, since that
     771           means a concurrent login somewhere else. */
     772        odata->no_reconnect = code == 1;
     773       
     774        /* DO NOT log out here! Just tell the callback to do it. */
     775        odata->killme = TRUE;
    749776
    750777        return 1;
     
    19391966        aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
    19401967
    1941         if (ic->away)
    1942                 g_free(ic->away);
     1968        g_free(ic->away);
    19431969        ic->away = NULL;
    19441970
     
    19601986static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od, const char *state, const char *message)
    19611987{
    1962     const char *msg = NULL;
     1988        const char *msg = NULL;
    19631989        gboolean no_message = FALSE;
    19641990
    19651991        /* clean old states */
    1966     if (ic->away) {
    1967                 g_free(ic->away);
    1968                 ic->away = NULL;
    1969     }
     1992        g_free(ic->away);
     1993        ic->away = NULL;
    19701994        od->sess->aim_icq_state = 0;
    19711995
    19721996        /* if no message, then use an empty message */
    1973     if (message) {
    1974         msg = message;
    1975     } else {
    1976         msg = "";
     1997        if (message) {
     1998                msg = message;
     1999        } else {
     2000                msg = "";
    19772001                no_message = TRUE;
    1978     }
     2002        }
    19792003
    19802004        if (!g_strcasecmp(state, "Online")) {
     
    19822006        } else if (!g_strcasecmp(state, "Away")) {
    19832007                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
    1984         ic->away = g_strdup(msg);
     2008                ic->away = g_strdup(msg);
    19852009                od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY;
    19862010        } else if (!g_strcasecmp(state, "Do Not Disturb")) {
    19872011                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY);
    1988         ic->away = g_strdup(msg);
     2012                ic->away = g_strdup(msg);
    19892013                od->sess->aim_icq_state = AIM_MTYPE_AUTODND;
    19902014        } else if (!g_strcasecmp(state, "Not Available")) {
    19912015                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
    1992         ic->away = g_strdup(msg);
     2016                ic->away = g_strdup(msg);
    19932017                od->sess->aim_icq_state = AIM_MTYPE_AUTONA;
    19942018        } else if (!g_strcasecmp(state, "Occupied")) {
    19952019                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY);
    1996         ic->away = g_strdup(msg);
     2020                ic->away = g_strdup(msg);
    19972021                od->sess->aim_icq_state = AIM_MTYPE_AUTOBUSY;
    19982022        } else if (!g_strcasecmp(state, "Free For Chat")) {
    19992023                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT);
    2000         ic->away = g_strdup(msg);
     2024                ic->away = g_strdup(msg);
    20012025                od->sess->aim_icq_state = AIM_MTYPE_AUTOFFC;
    20022026        } else if (!g_strcasecmp(state, "Invisible")) {
    20032027                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE);
    2004         ic->away = g_strdup(msg);
     2028                ic->away = g_strdup(msg);
    20052029        } else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) {
    20062030                if (no_message) {
     
    20082032                } else {
    20092033                        aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
    2010             ic->away = g_strdup(msg);
     2034                        ic->away = g_strdup(msg);
    20112035                        od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY;
    20122036                }
     
    20202044        struct oscar_data *od = (struct oscar_data *)ic->proto_data;
    20212045
    2022     oscar_set_away_aim(ic, od, state, message);
     2046        oscar_set_away_aim(ic, od, state, message);
    20232047        if (od->icq)
    20242048                oscar_set_away_icq(ic, od, state, message);
     
    25812605}
    25822606
    2583 struct groupchat *oscar_chat_join(struct im_connection * ic, char * room, char * nick, char * password )
     2607struct groupchat *oscar_chat_join(struct im_connection * ic, const char * room, const char * nick, const char * password )
    25842608{
    25852609        struct oscar_data * od = (struct oscar_data *)ic->proto_data;
  • protocols/yahoo/yahoo.c

    r823de9d r673a54c  
    197197{
    198198        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
    199        
    200         ic->away = NULL;
     199        char *away;
     200       
     201        away = NULL;
    201202       
    202203        if( state && msg && g_strcasecmp( state, msg ) != 0 )
    203204        {
    204205                yd->current_status = YAHOO_STATUS_CUSTOM;
    205                 ic->away = "";
     206                away = "";
    206207        }
    207208        else if( state )
     
    212213                msg = NULL;
    213214               
    214                 ic->away = "";
     215                away = "";
    215216                if( g_strcasecmp( state, "Available" ) == 0 )
    216217                {
    217218                        yd->current_status = YAHOO_STATUS_AVAILABLE;
    218                         ic->away = NULL;
     219                        away = NULL;
    219220                }
    220221                else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
     
    242243                        yd->current_status = YAHOO_STATUS_AVAILABLE;
    243244                       
    244                         ic->away = NULL;
     245                        away = NULL;
    245246                }
    246247        }
     
    248249                yd->current_status = YAHOO_STATUS_AVAILABLE;
    249250       
    250         yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );
     251        yahoo_set_away( yd->y2_id, yd->current_status, msg, away != NULL ? 2 : 0 );
    251252}
    252253
     
    791792{
    792793        struct byahoo_conf_invitation *inv = data;
    793        
    794         yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
    795         imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
     794        struct groupchat *b;
     795       
     796        for( b = inv->ic->groupchats; b; b = b->next )
     797                if( b == inv->c )
     798                        break;
     799       
     800        if( b != NULL )
     801        {
     802                yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
     803                imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
     804        }
     805        else
     806        {
     807                imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name );
     808        }
     809       
    796810        g_free( inv->name );
    797811        g_free( inv );
  • root_commands.c

    r823de9d r673a54c  
    7979}
    8080
     81#define MIN_ARGS( x, y... )                                                    \
     82        do                                                                     \
     83        {                                                                      \
     84                int blaat;                                                     \
     85                for( blaat = 0; blaat <= x; blaat ++ )                         \
     86                        if( cmd[blaat] == NULL )                               \
     87                        {                                                      \
     88                                irc_usermsg( irc, "Not enough parameters given (need %d).", x ); \
     89                                return y;                                      \
     90                        }                                                      \
     91        } while( 0 )
     92
    8193void root_command( irc_t *irc, char *cmd[] )
    8294{       
     
    89101                if( g_strcasecmp( commands[i].command, cmd[0] ) == 0 )
    90102                {
    91                         if( !cmd[commands[i].required_parameters] )
    92                         {
    93                                 irc_usermsg( irc, "Not enough parameters given (need %d)", commands[i].required_parameters );
    94                                 return;
    95                         }
     103                        MIN_ARGS( commands[i].required_parameters );
     104                       
    96105                        commands[i].execute( irc, cmd );
    97106                        return;
     
    251260}
    252261
     262typedef set_t** (*cmd_set_findhead)( irc_t*, char* );
     263typedef int (*cmd_set_checkflags)( irc_t*, set_t *set );
     264
     265static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead, cmd_set_checkflags checkflags )
     266{
     267        char *set_full = NULL, *set_name = NULL, *tmp;
     268        set_t **head;
     269       
     270        if( cmd[1] && g_strncasecmp( cmd[1], "-del", 4 ) == 0 )
     271        {
     272                MIN_ARGS( 2, 0 );
     273                set_full = cmd[2];
     274        }
     275        else
     276                set_full = cmd[1];
     277       
     278        if( findhead == NULL )
     279        {
     280                set_name = set_full;
     281               
     282                head = &irc->set;
     283        }
     284        else
     285        {
     286                char *id;
     287               
     288                if( ( tmp = strchr( set_full, '/' ) ) )
     289                {
     290                        id = g_strndup( set_full, ( tmp - set_full ) );
     291                        set_name = tmp + 1;
     292                }
     293                else
     294                {
     295                        id = g_strdup( set_full );
     296                }
     297               
     298                if( ( head = findhead( irc, id ) ) == NULL )
     299                {
     300                        g_free( id );
     301                        irc_usermsg( irc, "Could not find setting." );
     302                        return 0;
     303                }
     304                g_free( id );
     305        }
     306       
     307        if( cmd[1] && cmd[2] && set_name )
     308        {
     309                set_t *s = set_find( head, set_name );
     310                int st;
     311               
     312                if( checkflags && checkflags( irc, s ) == 0 )
     313                        return 0;
     314               
     315                if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 )
     316                        st = set_reset( head, set_name );
     317                else
     318                        st = set_setstr( head, set_name, cmd[2] );
     319               
     320                if( set_getstr( head, set_name ) == NULL )
     321                {
     322                        if( st )
     323                                irc_usermsg( irc, "Setting changed successfully" );
     324                        else
     325                                irc_usermsg( irc, "Failed to change setting" );
     326                }
     327                else
     328                {
     329                        cmd_showset( irc, head, set_name );
     330                }
     331        }
     332        else if( set_name )
     333        {
     334                cmd_showset( irc, head, set_name );
     335        }
     336        else
     337        {
     338                set_t *s = *head;
     339                while( s )
     340                {
     341                        cmd_showset( irc, &s, s->key );
     342                        s = s->next;
     343                }
     344        }
     345       
     346        return 1;
     347}
     348
     349static set_t **cmd_account_set_findhead( irc_t *irc, char *id )
     350{
     351        account_t *a;
     352       
     353        if( ( a = account_get( irc, id ) ) )
     354                return &a->set;
     355        else
     356                return NULL;
     357}
     358
     359static int cmd_account_set_checkflags( irc_t *irc, set_t *s )
     360{
     361        account_t *a = s->data;
     362       
     363        if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY )
     364        {
     365                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" );
     366                return 0;
     367        }
     368        else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY )
     369        {
     370                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" );
     371                return 0;
     372        }
     373       
     374        return 1;
     375}
     376
    253377static void cmd_account( irc_t *irc, char **cmd )
    254378{
     
    265389                struct prpl *prpl;
    266390               
    267                 if( cmd[2] == NULL || cmd[3] == NULL || cmd[4] == NULL )
    268                 {
    269                         irc_usermsg( irc, "Not enough parameters" );
    270                         return;
    271                 }
    272                
    273                 prpl = find_protocol(cmd[2]);
     391                MIN_ARGS( 4 );
     392               
     393                prpl = find_protocol( cmd[2] );
    274394               
    275395                if( prpl == NULL )
     
    295415        else if( g_strcasecmp( cmd[1], "del" ) == 0 )
    296416        {
    297                 if( !cmd[2] )
    298                 {
    299                         irc_usermsg( irc, "Not enough parameters given (need %d)", 2 );
    300                 }
    301                 else if( !( a = account_get( irc, cmd[2] ) ) )
     417                MIN_ARGS( 2 );
     418
     419                if( !( a = account_get( irc, cmd[2] ) ) )
    302420                {
    303421                        irc_usermsg( irc, "Invalid account" );
     
    427545        else if( g_strcasecmp( cmd[1], "set" ) == 0 )
    428546        {
    429                 char *acc_handle, *set_name = NULL, *tmp;
    430                
    431                 if( !cmd[2] )
    432                 {
    433                         irc_usermsg( irc, "Not enough parameters given (need %d)", 2 );
    434                         return;
    435                 }
    436                
    437                 if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 )
    438                         acc_handle = g_strdup( cmd[3] );
    439                 else
    440                         acc_handle = g_strdup( cmd[2] );
    441                
    442                 if( !acc_handle )
    443                 {
    444                         irc_usermsg( irc, "Not enough parameters given (need %d)", 3 );
    445                         return;
    446                 }
    447                
    448                 if( ( tmp = strchr( acc_handle, '/' ) ) )
    449                 {
    450                         *tmp = 0;
    451                         set_name = tmp + 1;
    452                 }
    453                
    454                 if( ( a = account_get( irc, acc_handle ) ) == NULL )
    455                 {
    456                         g_free( acc_handle );
    457                         irc_usermsg( irc, "Invalid account" );
    458                         return;
    459                 }
    460                
    461                 if( cmd[3] && set_name )
    462                 {
    463                         set_t *s = set_find( &a->set, set_name );
    464                         int st;
    465                        
    466                         if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY )
    467                         {
    468                                 g_free( acc_handle );
    469                                 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" );
    470                                 return;
    471                         }
    472                         else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY )
    473                         {
    474                                 g_free( acc_handle );
    475                                 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" );
    476                                 return;
    477                         }
    478                        
    479                         if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 )
    480                                 st = set_reset( &a->set, set_name );
    481                         else
    482                                 st = set_setstr( &a->set, set_name, cmd[3] );
    483                        
    484                         if( set_getstr( &a->set, set_name ) == NULL )
    485                         {
    486                                 if( st )
    487                                         irc_usermsg( irc, "Setting changed successfully" );
    488                                 else
    489                                         irc_usermsg( irc, "Failed to change setting" );
    490                         }
    491                         else
    492                         {
    493                                 cmd_showset( irc, &a->set, set_name );
    494                         }
    495                 }
    496                 else if( set_name )
    497                 {
    498                         cmd_showset( irc, &a->set, set_name );
    499                 }
    500                 else
    501                 {
    502                         set_t *s = a->set;
    503                         while( s )
    504                         {
    505                                 cmd_showset( irc, &s, s->key );
    506                                 s = s->next;
    507                         }
    508                 }
    509                
    510                 g_free( acc_handle );
    511         }
    512         else
    513         {
    514                 irc_usermsg( irc, "Unknown command: account %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[1] );
     547                MIN_ARGS( 2 );
     548               
     549                cmd_set_real( irc, cmd + 1, cmd_account_set_findhead, cmd_account_set_checkflags );
     550        }
     551        else
     552        {
     553                irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[1] );
    515554        }
    516555}
     
    523562        if( g_strcasecmp( cmd[1], "-tmp" ) == 0 )
    524563        {
     564                MIN_ARGS( 3 );
    525565                add_on_server = 0;
    526566                cmd ++;
     
    842882static void cmd_set( irc_t *irc, char **cmd )
    843883{
    844         char *set_name = cmd[1];
    845        
    846         if( cmd[1] && cmd[2] )
    847         {
    848                 int st;
    849                
    850                 if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 )
    851                 {
    852                         st = set_reset( &irc->set, cmd[2] );
    853                         set_name = cmd[2];
    854                 }
    855                 else
    856                 {
    857                         st = set_setstr( &irc->set, cmd[1], cmd[2] );
    858                 }
    859                
    860                 /* Normally we just show the variable's new/unchanged
    861                    value as feedback to the user, but this has always
    862                    caused confusion when changing the password. Give
    863                    other feedback instead: */
    864                 if( set_getstr( &irc->set, set_name ) == NULL )
    865                 {
    866                         if( st )
    867                                 irc_usermsg( irc, "Setting changed successfully" );
    868                         else
    869                                 irc_usermsg( irc, "Failed to change setting" );
    870                 }
    871                 else
    872                 {
    873                         cmd_showset( irc, &irc->set, set_name );
    874                 }
    875         }
    876         else if( set_name )
    877         {
    878                 cmd_showset( irc, &irc->set, set_name );
    879 
    880                 if( strchr( set_name, '/' ) )
    881                         irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." );
    882         }
    883         else
    884         {
    885                 set_t *s = irc->set;
    886                 while( s )
    887                 {
    888                         cmd_showset( irc, &s, s->key );
    889                         s = s->next;
    890                 }
    891         }
     884        cmd_set_real( irc, cmd, NULL, NULL );
    892885}
    893886
     
    10121005static void cmd_join_chat( irc_t *irc, char **cmd )
    10131006{
     1007        irc_usermsg( irc, "This command is now obsolete. "
     1008                          "Please try the `chat' command instead." );
     1009}
     1010
     1011static set_t **cmd_chat_set_findhead( irc_t *irc, char *id )
     1012{
     1013        struct chat *c;
     1014       
     1015        if( ( c = chat_get( irc, id ) ) )
     1016                return &c->set;
     1017        else
     1018                return NULL;
     1019}
     1020
     1021static void cmd_chat( irc_t *irc, char **cmd )
     1022{
     1023        account_t *acc;
     1024        struct chat *c;
     1025       
     1026        if( g_strcasecmp( cmd[1], "add" ) == 0 )
     1027        {
     1028                char *channel, *s;
     1029               
     1030                MIN_ARGS( 3 );
     1031               
     1032                if( !( acc = account_get( irc, cmd[2] ) ) )
     1033                {
     1034                        irc_usermsg( irc, "Invalid account" );
     1035                        return;
     1036                }
     1037               
     1038                if( cmd[4] == NULL )
     1039                {
     1040                        channel = g_strdup( cmd[3] );
     1041                        if( ( s = strchr( channel, '@' ) ) )
     1042                                *s = 0;
     1043                }
     1044                else
     1045                {
     1046                        channel = g_strdup( cmd[4] );
     1047                }
     1048               
     1049                if( strchr( CTYPES, channel[0] ) == NULL )
     1050                {
     1051                        s = g_strdup_printf( "%c%s", CTYPES[0], channel );
     1052                        g_free( channel );
     1053                        channel = s;
     1054                }
     1055               
     1056                if( ( c = chat_add( irc, acc, cmd[3], channel ) ) )
     1057                        irc_usermsg( irc, "Chatroom added successfully." );
     1058                else
     1059                        irc_usermsg( irc, "Could not add chatroom." );
     1060               
     1061                g_free( channel );
     1062        }
     1063        else if( g_strcasecmp( cmd[1], "list" ) == 0 )
     1064        {
     1065                int i = 0;
     1066               
     1067                if( strchr( irc->umode, 'b' ) )
     1068                        irc_usermsg( irc, "Chatroom list:" );
     1069               
     1070                for( c = irc->chatrooms; c; c = c->next )
     1071                {
     1072                        irc_usermsg( irc, "%2d. %s(%s) %s, %s", i, c->acc->prpl->name,
     1073                                          c->acc->user, c->handle, c->channel );
     1074                       
     1075                        i ++;
     1076                }
     1077                irc_usermsg( irc, "End of chatroom list" );
     1078        }
     1079        else if( g_strcasecmp( cmd[1], "set" ) == 0 )
     1080        {
     1081                cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead, NULL );
     1082        }
     1083        else if( g_strcasecmp( cmd[1], "del" ) == 0 )
     1084        {
     1085                MIN_ARGS( 2 );
     1086               
     1087                if( ( c = chat_get( irc, cmd[2] ) ) )
     1088                {
     1089                        chat_del( irc, c );
     1090                }
     1091                else
     1092                {
     1093                        irc_usermsg( irc, "Could not remove chat." );
     1094                }
     1095        }
     1096        else if( g_strcasecmp( cmd[1], "with" ) == 0 )
     1097        {
     1098                user_t *u;
     1099               
     1100                MIN_ARGS( 2 );
     1101               
     1102                if( ( u = user_find( irc, cmd[2] ) ) && u->ic && u->ic->acc->prpl->chat_with )
     1103                {
     1104                        if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) )
     1105                        {
     1106                                irc_usermsg( irc, "(Possible) failure while trying to open "
     1107                                                  "a groupchat with %s.", u->nick );
     1108                        }
     1109                }
     1110                else
     1111                {
     1112                        irc_usermsg( irc, "Can't open a groupchat with %s.", cmd[2] );
     1113                }
     1114        }
     1115        else
     1116        {
     1117                irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] );
     1118        }
     1119
     1120
     1121
     1122#if 0
    10141123        account_t *a;
    10151124        struct im_connection *ic;
     
    10371146        if( cmd[3] )
    10381147        {
    1039                 if( cmd[3][0] != '#' && cmd[3][0] != '&' )
     1148                if( strchr( CTYPES, cmd[3][0] ) == NULL )
    10401149                        channel = g_strdup_printf( "&%s", cmd[3] );
    10411150                else
     
    10801189                g_free( channel );
    10811190        }
     1191#endif
    10821192}
    10831193
     
    11031213        { "join_chat",      2, cmd_join_chat,      0 },
    11041214        { "otr",            1, cmd_otr,            0 },
     1215        { "chat",           1, cmd_chat,           0 },
    11051216        { NULL }
    11061217};
  • set.c

    r823de9d r673a54c  
    267267                mode=3;
    268268        else
    269                 return NULL;
     269                return SET_INVALID;
    270270
    271271        /* sorry for calling them op/deop - too lazy for search+replace :P */
  • storage.c

    r823de9d r673a54c  
    121121                        return status;
    122122                }
    123                
    124123                if (status != STORAGE_NO_SUCH_USER)
    125124                        return status;
  • storage_xml.c

    r823de9d r673a54c  
    3838#endif
    3939
    40 #if !GLIB_CHECK_VERSION(2,8,0)
    41 /* GLib < 2.8.0 doesn't have g_access, so just use the system access(). */
    42 #define g_access access
    43 #endif
    44 
    4540typedef enum
    4641{
     
    5954        char *current_setting;
    6055        account_t *current_account;
     56        struct chat *current_chat;
     57        set_t **current_set_head;
    6158        char *given_nick;
    6259        char *given_pass;
     
    177174               
    178175                if( ( setting = xml_attr( attr_names, attr_values, "name" ) ) )
     176                {
     177                        if( xd->current_chat != NULL )
     178                                xd->current_set_head = &xd->current_chat->set;
     179                        else if( xd->current_account != NULL )
     180                                xd->current_set_head = &xd->current_account->set;
     181                        else
     182                                xd->current_set_head = &xd->irc->set;
     183                       
    179184                        xd->current_setting = g_strdup( setting );
     185                }
    180186                else
    181187                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
     
    199205                }
    200206        }
     207        else if( g_strcasecmp( element_name, "chat" ) == 0 )
     208        {
     209                char *handle, *channel;
     210               
     211                handle = xml_attr( attr_names, attr_values, "handle" );
     212                channel = xml_attr( attr_names, attr_values, "channel" );
     213               
     214                if( xd->current_account && handle && channel )
     215                {
     216                        xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel );
     217                }
     218                else
     219                {
     220                        g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
     221                                     "Missing attributes for %s element", element_name );
     222                }
     223        }
    201224        else
    202225        {
     
    219242                xd->current_account = NULL;
    220243        }
     244        else if( g_strcasecmp( element_name, "chat" ) == 0 )
     245        {
     246                xd->current_chat = NULL;
     247        }
    221248}
    222249
     
    225252        char text[text_len+1];
    226253        struct xml_parsedata *xd = data;
    227         irc_t *irc = xd->irc;
    228254       
    229255        strncpy( text, text_orig, text_len );
     
    238264        else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && xd->current_setting )
    239265        {
    240                 set_setstr( xd->current_account ? &xd->current_account->set : &irc->set,
    241                             xd->current_setting, (char*) text );
     266                set_setstr( xd->current_set_head, xd->current_setting, (char*) text );
    242267                g_free( xd->current_setting );
    243268                xd->current_setting = NULL;
     
    402427       
    403428        for( set = irc->set; set; set = set->next )
    404                 if( set->value && set->def )
     429                if( set->value )
    405430                        if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
    406431                                goto write_error;
     
    411436                char *pass_b64;
    412437                int pass_len;
     438                struct chat *c;
    413439               
    414440                pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 );
     
    429455               
    430456                for( set = acc->set; set; set = set->next )
    431                         if( set->value && set->def && !( set->flags & ACC_SET_NOSAVE ) )
     457                        if( set->value && !( set->flags & ACC_SET_NOSAVE ) )
    432458                                if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
    433459                                        goto write_error;
     
    443469                        goto write_error;
    444470               
     471                for( c = irc->chatrooms; c; c = c->next )
     472                {
     473                        if( c->acc != acc )
     474                                continue;
     475                       
     476                        if( !xml_printf( fd, 2, "<chat handle=\"%s\" channel=\"%s\" type=\"%s\">\n",
     477                                                c->handle, c->channel, "room" ) )
     478                                goto write_error;
     479                       
     480                        for( set = c->set; set; set = set->next )
     481                                if( set->value && !( set->flags & ACC_SET_NOSAVE ) )
     482                                        if( !xml_printf( fd, 3, "<setting name=\"%s\">%s</setting>\n",
     483                                                                set->key, set->value ) )
     484                                                goto write_error;
     485
     486                        if( !xml_printf( fd, 2, "</chat>\n" ) )
     487                                goto write_error;
     488                }
     489               
    445490                if( !xml_printf( fd, 1, "</account>\n" ) )
    446491                        goto write_error;
  • tests/Makefile

    r823de9d r673a54c  
    1111distclean: clean
    1212
    13 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o
     13main_objs = account.o bitlbee.o chat.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o
    1414
    1515test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_crypting.o check_set.o check_jabber_sasl.o check_jabber_util.o
  • tests/check_set.c

    r823de9d r673a54c  
    9696END_TEST
    9797
    98 START_TEST(test_setstr_implicit)
    99         void *data = "data";
    100         set_t *s = NULL, *t;
    101         set_setstr(&s, "name", "bloe");
    102         fail_unless(set_find(&s, "name") != NULL);
    103 END_TEST
    104 
    10598START_TEST(test_set_get_int_unknown)
    10699        set_t *s = NULL;
     
    126119        tcase_add_test (tc_core, test_setint);
    127120        tcase_add_test (tc_core, test_setstr);
    128         tcase_add_test (tc_core, test_setstr_implicit);
    129121        return s;
    130122}
Note: See TracChangeset for help on using the changeset viewer.