Changes in / [3fbce97:63cad66]


Ignore:
Files:
2 deleted
117 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    r3fbce97 r63cad66  
    1 sudo: false
    21language: c
    32
     
    54 - ./configure
    65 - make check
    7  - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d
     6 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us
    87
    9 # ubuntu precise doesn't have libotr5, so extract a prebuilt version to ~/otr
    108before_install:
    11  - wget http://dump.dequis.org/indexed/bitlbee-travis-libs/libotr5_4.1.0_amd64_with_dev_for_travis.tar.gz -O /tmp/otr.tar.gz
    12  - echo "8424feb28a2cff3ce603ddcdff9be788701ff7e4  /tmp/otr.tar.gz" | sha1sum -c -
    13  - tar -C "$HOME" -xf /tmp/otr.tar.gz
    14  - sed -i "s#/usr#$HOME/otr/usr/#" "$HOME/otr/usr/lib/pkgconfig/libotr.pc"
    15  - echo "libotr 5 libotr" > debian/shlibs.local
     9 - sudo apt-get update -qq
     10 - sudo apt-get install --no-install-recommends -qq libevent-dev libpurple-dev check
     11 - wget http://dump.dequis.org/indexed/bitlbee-travis-libs/libotr5{,-dev}_4.1.0-2~bpo70+1_amd64.deb
     12 - sudo dpkg -i *.deb
    1613
    1714env:
    1815  global:
    19    - PKG_CONFIG_PATH=$HOME/otr/usr/lib/pkgconfig/
    20    - LD_LIBRARY_PATH=$HOME/otr/usr/lib/
    2116   # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
    2217   #   via the "travis encrypt" command using the project repo's public key
     
    2419
    2520addons:
    26   apt:
    27     packages:
    28     - libevent-dev
    29     - libpurple-dev
    30     - check
    3121  coverity_scan:
    3222    project:
  • Makefile

    r3fbce97 r63cad66  
    1010
    1111# Program variables
    12 objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_cap.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o $(OTR_BI) query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o conf.o log.o
     12objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o $(OTR_BI) query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o conf.o log.o
    1313headers = $(wildcard $(_SRCDIR_)*.h $(_SRCDIR_)lib/*.h $(_SRCDIR_)protocols/*.h)
    1414subdirs = lib protocols
     
    3030
    3131install: install-bin install-doc install-plugins
    32         @echo
    33         @echo Installed successfully
    34         @echo
    3532        @if ! [ -d $(DESTDIR)$(CONFIG) ]; then echo -e '\nThe configuration directory $(DESTDIR)$(CONFIG) does not exist yet, don'\''t forget to create it!'; fi
    3633        @if ! [ -e $(DESTDIR)$(ETCDIR)/bitlbee.conf ]; then echo -e '\nNo files are installed in '$(DESTDIR)$(ETCDIR)' by make install. Run make install-etc to do that.'; fi
     
    3835        @echo If you want to start BitlBee using systemd, try \"make install-systemd\".
    3936endif
    40         @echo To be able to compile third party plugins, run \"make install-dev\"
    4137        @echo
    4238
    43 .PHONY:   install   install-bin   install-etc   install-doc install-plugins install-systemd install-dev \
    44         uninstall uninstall-bin uninstall-etc uninstall-doc uninstall-etc \
     39.PHONY:   install   install-bin   install-etc   install-doc install-plugins install-systemd \
     40        uninstall uninstall-bin uninstall-etc uninstall-doc \
    4541        all clean distclean tar $(subdirs) doc
    4642
  • README.md

    r3fbce97 r63cad66  
    1616License: GPLv2
    1717
    18 ## Installation
     18## Development
    1919
    20 BitlBee is available in the package managers of most distros.
     20Use github pull requests against the 'develop' branch to submit patches.
    2121
    22 For debian/ubuntu/etc you may use the nightly APT repository: http://code.bitlbee.org/debian/
     22The 'master' branch should be stable enough to be usable by users of the APT repo, but only requires a few days of testing in the 'develop' branch.
    2323
    24 You can also use a public server (such as `im.bitlbee.org`) instead of installing it: http://bitlbee.org/main.php/servers.html
     24Building:
    2525
    26 ## Compiling
     26```
     27./configure --debug=1
     28# or, for a local install:
     29# ./configure --debug=1 --prefix=$HOME/bitlbee --config=$HOME/bitlbee --pidfile=$HOME/bitlbee/bitlbee.pid
    2730
    28 If you wish to compile it yourself, ensure you have the following packages and their headers:
     31# Also try --asan=1 for AddressSanitizer
    2932
    30 * glib 2.16 or newer (not to be confused with glibc)
    31 * gnutls
    32 * python 2 or 3 (for the user guide)
     33make
    3334
    34 Some optional features have additional dependencies, such as libpurple, libotr, libevent, etc.
    35 NSS and OpenSSL are also available but not as well supported as GnuTLS.
     35BITLBEE_DEBUG=1 ./bitlbee -Dnv
     36```
    3637
    37 Once you have the dependencies, building should be a matter of:
     38See ./doc/README and ./doc/HACKING for more details.
    3839
    39     ./configure
    40     make
    41     sudo make install
    42 
    43 ## Development tips
    44 
    45 * To enable debug symbols: `./configure --debug=1`
    46 * To get some additional debug output for some protocols: `BITLBEE_DEBUG=1 ./bitlbee -Dnv`
    47 * Use github pull requests against the 'develop' branch to submit patches.
    48 * The coding style based on K&R with tabs and 120 columns. See `./doc/uncrustify.cfg` for the parameters used to reformat the code.
    49 * Mappings of bzr revisions to git commits (for historical purposes) are available in `./doc/git-bzr-rev-map`
    50 * See also `./doc/README` and `./doc/HACKING`
     40Mappings of bzr revisions to git commits (for historical purposes) are available in ./doc/git-bzr-rev-map
    5141
    5242## Help?
    5343
    54 Join **#BitlBee** on OFTC (**irc.oftc.net**) (OFTC, *not* FreeNode!)
     44Join **#BitlBee** on OFTC (**irc.oftc.net**) (OFTC, *not* FreeNode!) and flame us right in the face. :-)
  • bitlbee.c

    r3fbce97 r63cad66  
    311311                        b_event_remove(global.listen_watch_source_id);
    312312
    313                         /* Make a new pipe for the shutdown signal handler */
    314                         sighandler_shutdown_setup();
    315 
    316313                        /* Make the connection. */
    317314                        irc = irc_new(new_socket);
  • bitlbee.h

    r3fbce97 r63cad66  
    158158} global_t;
    159159
    160 void sighandler_shutdown_setup(void);
    161 
    162160int bitlbee_daemon_init(void);
    163161int bitlbee_inetd_init(void);
  • conf.c

    r3fbce97 r63cad66  
    3737
    3838static int conf_loadini(conf_t *conf, char *file);
    39 static void conf_free(conf_t *conf);
    4039
    4140conf_t *conf_load(int argc, char *argv[])
     
    7473        if (i == 0) {
    7574                fprintf(stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file);
    76                 conf_free(conf);
    7775                return NULL;
    7876        } else if (i == -1) {
     
    106104                                g_free(global.conf_file);
    107105                                global.conf_file = g_strdup(optarg);
    108                                 conf_free(conf);
     106                                g_free(conf);
    109107                                /* Re-evaluate arguments. Don't use this option twice,
    110108                                   you'll end up in an infinite loop! Hope this trick
     
    137135                               "  -h  Show this help page.\n"
    138136                               "  -V  Show version info.\n");
    139                         conf_free(conf);
    140137                        return NULL;
    141138                } else if (opt == 'V') {
    142                         printf("BitlBee %s\nAPI version %06x\nConfigure args: %s\n",
    143                                BITLBEE_VERSION, BITLBEE_VERSION_CODE, BITLBEE_CONFIGURE_ARGS);
    144                         conf_free(conf);
     139                        printf("BitlBee %s\nAPI version %06x\n",
     140                               BITLBEE_VERSION, BITLBEE_VERSION_CODE);
    145141                        return NULL;
    146142                } else if (opt == 'u') {
     
    166162                   they're secure when in fact they're not. */
    167163                fprintf(stderr, "Error: Could not read CA file %s: %s\n", conf->cafile, strerror(errno));
    168                 conf_free(conf);
    169164                return NULL;
    170165        }
    171166
    172167        return conf;
    173 }
    174 
    175 static void conf_free(conf_t *conf)
    176 {
    177         /* Free software means users have the four essential freedoms:
    178            0. to run the program,
    179            2. to study and change the program in source code form,
    180            2. to redistribute exact copies, and
    181            3. to distribute modified versions
    182         */
    183         g_free(conf->auth_pass);
    184         g_free(conf->cafile);
    185         g_free(conf->configdir);
    186         g_free(conf->ft_listen);
    187         g_free(conf->hostname);
    188         g_free(conf->iface_in);
    189         g_free(conf->iface_out);
    190         g_free(conf->motdfile);
    191         g_free(conf->oper_pass);
    192         g_free(conf->pidfile);
    193         g_free(conf->plugindir);
    194         g_free(conf->port);
    195         g_free(conf->primary_storage);
    196         g_free(conf->user);
    197         g_strfreev(conf->migrate_storage);
    198         g_strfreev(conf->protocols);
    199         g_free(conf);
    200 
    201168}
    202169
     
    252219                                g_free(conf->configdir);
    253220                                conf->configdir = g_strdup(ini->value);
    254                         } else if (g_strcasecmp(ini->key, "plugindir") == 0) {
    255                                 g_free(conf->plugindir);
    256                                 conf->plugindir = g_strdup(ini->value);
    257221                        } else if (g_strcasecmp(ini->key, "motdfile") == 0) {
    258222                                g_free(conf->motdfile);
     
    295259                                } else if (url->proto == PROTO_SOCKS5) {
    296260                                        proxytype = PROXY_SOCKS5;
    297                                 } else if (url->proto == PROTO_SOCKS4A) {
    298                                         proxytype = PROXY_SOCKS4A;
    299261                                }
    300262
  • configure

    r3fbce97 r63cad66  
    2424pcdir='$prefix/lib/pkgconfig'
    2525systemlibdirs="/lib64 /usr/lib64 /usr/local/lib64 /lib /usr/lib /usr/local/lib"
    26 sysroot=''
    27 
    28 configure_args="$@"
    2926
    3027# Set these to default-on to let it be overriden by either the user or purple
     
    5653pie=1
    5754
    58 arch=$(uname -s)
    59 cpu=$(uname -m)
     55arch=`uname -s`
     56cpu=`uname -m`
    6057
    6158GLIB_MIN_VERSION=2.16
     
    108105
    109106while [ -n "$1" ]; do
    110         e="$(expr "X$1" : 'X--\(.*=.*\)')"
     107        e="`expr "X$1" : 'X--\(.*=.*\)'`"
    111108        if [ -z "$e" ]; then
    112109                cat<<EOF
     
    156153
    157154--target=...    Cross compilation target                same as host
    158 --sysroot=...   Cross compilation sysroot               $sysroot
    159155EOF
    160156                exit;
     
    165161
    166162# Expand $prefix and get rid of double slashes
    167 bindir=$(eval echo "$bindir/" | sed 's/\/\{1,\}/\//g')
    168 sbindir=$(eval echo "$sbindir/" | sed 's/\/\{1,\}/\//g')
    169 etcdir=$(eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g')
    170 mandir=$(eval echo "$mandir/" | sed 's/\/\{1,\}/\//g')
    171 datadir=$(eval echo "$datadir/" | sed 's/\/\{1,\}/\//g')
    172 config=$(eval echo "$config/" | sed 's/\/\{1,\}/\//g')
    173 plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g')
     163bindir=`eval echo "$bindir/" | sed 's/\/\{1,\}/\//g'`
     164sbindir=`eval echo "$sbindir/" | sed 's/\/\{1,\}/\//g'`
     165etcdir=`eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g'`
     166mandir=`eval echo "$mandir/" | sed 's/\/\{1,\}/\//g'`
     167datadir=`eval echo "$datadir/" | sed 's/\/\{1,\}/\//g'`
     168config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'`
     169plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'`
    174170rpcplugindir=$(eval echo "$rpcplugindir/" | sed 's/\/\{1,\}/\//g')
    175 includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g')
    176 libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g')
    177 
    178 pidfile=$(eval echo "$pidfile" | sed 's/\/\{1,\}/\//g')
    179 ipcsocket=$(eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g')
    180 pcdir=$(eval echo "$pcdir" | sed 's/\/\{1,\}/\//g')
     171includedir=`eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g'`
     172libevent=`eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g'`
     173
     174pidfile=`eval echo "$pidfile" | sed 's/\/\{1,\}/\//g'`
     175ipcsocket=`eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g'`
     176pcdir=`eval echo "$pcdir" | sed 's/\/\{1,\}/\//g'`
    181177
    182178protocols_mods=""
     
    184180cat <<EOF >Makefile.settings
    185181## BitlBee settings, generated by configure
    186 
    187 # ./configure $configure_args
    188 
    189182PREFIX=$prefix
    190183BINDIR=$bindir
     
    240233   of them can/will be overridden at run-time */
    241234
    242 #define BITLBEE_CONFIGURE_ARGS "$configure_args"
    243 
    244235#define CONFIG "$config"
    245236#define ETCDIR "$etcdir"
     
    256247
    257248if [ -n "$target" ]; then
    258         # prepend sysroot to system lib dirs
    259 
    260         systemlibdirs_cross=''
    261         for i in $systemlibdirs; do
    262                 systemlibdirs_cross="$systemlibdirs_cross $sysroot$i"
    263         done
    264         systemlibdirs=$systemlibdirs_cross
    265         unset systemlibdirs_cross
    266 
    267         # backward compatibility
    268 
    269         if [ -z "$PKG_CONFIG_LIBDIR" ]; then
    270                 PKG_CONFIG_LIBDIR=/usr/$target/lib/pkgconfig
    271                 export PKG_CONFIG_LIBDIR
    272         fi
    273 
    274         if [ -d /usr/$target/bin ]; then
    275                 PATH=/usr/$target/bin:$PATH
    276         fi
    277 
    278         if [ -d /usr/$target/lib ]; then
    279                 systemlibdirs="$systemlibdirs /usr/$target/lib"
    280         fi
    281 
     249        PKG_CONFIG_LIBDIR=/usr/$target/lib/pkgconfig
     250        export PKG_CONFIG_LIBDIR
     251        PATH=/usr/$target/bin:$PATH
    282252        CC=$target-cc
    283253        LD=$target-ld
    284         STRIP=$target-strip
     254        systemlibdirs="/usr/$target/lib"
    285255fi
    286256
     
    351321        if $PKG_CONFIG glib-2.0 --atleast-version=$GLIB_MIN_VERSION; then
    352322                cat<<EOF >>Makefile.settings
    353 EFLAGS+=$($PKG_CONFIG --libs glib-2.0 gmodule-2.0)
    354 CFLAGS+=$($PKG_CONFIG --cflags glib-2.0 gmodule-2.0)
     323EFLAGS+=`$PKG_CONFIG --libs glib-2.0 gmodule-2.0`
     324CFLAGS+=`$PKG_CONFIG --cflags glib-2.0 gmodule-2.0`
    355325EOF
    356326        else
    357327                echo
    358                 echo 'Found glib2 '$($PKG_CONFIG glib-2.0 --modversion)', but version '$GLIB_MIN_VERSION' or newer is required.'
     328                echo 'Found glib2 '`$PKG_CONFIG glib-2.0 --modversion`', but version '$GLIB_MIN_VERSION' or newer is required.'
    359329                exit 1
    360330        fi
     
    392362        if $PKG_CONFIG --exists gnutls; then
    393363                cat <<EOF >>Makefile.settings
    394 EFLAGS+=$($PKG_CONFIG --libs gnutls) $(libgcrypt-config --libs)
    395 CFLAGS+=$($PKG_CONFIG --cflags gnutls) $(libgcrypt-config --cflags)
     364EFLAGS+=`$PKG_CONFIG --libs gnutls` `libgcrypt-config --libs`
     365CFLAGS+=`$PKG_CONFIG --cflags gnutls` `libgcrypt-config --cflags`
    396366EOF
    397367                ssl=gnutls
    398                 if ! $PKG_CONFIG gnutls --atleast-version=2.8; then
     368                if ! pkg-config gnutls --atleast-version=2.8; then
    399369                        echo
    400370                        echo 'Warning: With GnuTLS versions <2.8, certificate expire dates are not verified.'
     
    403373        elif libgnutls-config --version > /dev/null 2> /dev/null; then
    404374                cat <<EOF >>Makefile.settings
    405 EFLAGS+=$(libgnutls-config --libs) $(libgcrypt-config --libs)
    406 CFLAGS+=$(libgnutls-config --cflags) $(libgcrypt-config --cflags)
     375EFLAGS+=`libgnutls-config --libs` `libgcrypt-config --libs`
     376CFLAGS+=`libgnutls-config --cflags` `libgcrypt-config --cflags`
    407377EOF
    408378               
     
    418388        if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG nss; then
    419389                cat<<EOF >>Makefile.settings
    420 EFLAGS+=$($PKG_CONFIG --libs nss)
    421 CFLAGS+=$($PKG_CONFIG --cflags nss)
     390EFLAGS+=`$PKG_CONFIG --libs nss`
     391CFLAGS+=`$PKG_CONFIG --cflags nss`
    422392EOF
    423393               
     
    664634if [ -z "$systemdsystemunitdir" ]; then
    665635        if $PKG_CONFIG --exists systemd; then
    666                 systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
     636                systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd`
    667637        fi
    668638fi
     
    692662
    693663otrprefix=""
     664for i in / /usr /usr/local; do
     665        if [ -f ${i}/lib/libotr.a ]; then
     666                otrprefix=${i}
     667                break
     668        fi
     669done
    694670if [ "$otr" = "auto" ]; then
    695         ! $PKG_CONFIG --exists libotr
    696         otr=$?
    697 fi
    698 
    699 if [ "$otr" != 0 ] && ! $PKG_CONFIG --atleast-version=4.0 --print-errors libotr; then
    700         exit 1
    701 fi
    702 
     671        if [ -n "$otrprefix" ]; then
     672                otr=1
     673        else
     674                otr=0
     675        fi
     676fi
    703677if [ "$otr" = 1 ]; then
    704678        # BI == built-in
    705679        echo '#define OTR_BI' >> config.h
    706         echo "EFLAGS+=$($PKG_CONFIG --libs libotr) $(libgcrypt-config --libs)" >> Makefile.settings
    707         echo "CFLAGS+=$($PKG_CONFIG --cflags libotr) $(libgcrypt-config --cflags)" >> Makefile.settings
     680        echo "EFLAGS+=-L${otrprefix}/lib -lotr -lgcrypt" >> Makefile.settings
     681        echo "CFLAGS+=-I${otrprefix}/include" >> Makefile.settings
    708682        echo 'OTR_BI=otr.o' >> Makefile.settings
    709683elif [ "$otr" = "plugin" ]; then
    710         # for some mysterious reason beyond the comprehension of my mortal mind,
    711         # the libgcrypt flags aren't needed when building as plugin. add them anyway.
    712684        echo '#define OTR_PI' >> config.h
    713         echo "OTRFLAGS=$($PKG_CONFIG --libs libotr) $(libgcrypt-config --libs)" >> Makefile.settings
    714         echo "CFLAGS+=$($PKG_CONFIG --cflags libotr) $(libgcrypt-config --cflags)" >> Makefile.settings
     685        echo "OTRFLAGS=-L${otrprefix}/lib -lotr" >> Makefile.settings
     686        echo "CFLAGS+=-I${otrprefix}/include" >> Makefile.settings
    715687        echo 'OTR_PI=otr.so' >> Makefile.settings
     688fi
     689if [ "$otr" != 0 ] && ! pkg-config libotr --atleast-version=4.0; then
     690        echo
     691        echo 'WARNING: Your libotr seems to be old. BitlBee now needs at least libotr 4.0.'
     692        # Not hard-failing because the code above doesn't use pkg-config, so who knows
     693        # what's true at this point...
    716694fi
    717695
  • dcc.c

    r3fbce97 r63cad66  
    265265                }
    266266
    267                 /* How likely is it that a 32-bit integer gets split across
     267                /* How likely is it that a 32-bit integer gets split accross
    268268                   packet boundaries? Chances are rarely 0 so let's be sure. */
    269269                if ((df->acked_len = (df->acked_len + ret) % 4) > 0) {
  • debian/changelog

    r3fbce97 r63cad66  
    1 bitlbee (3.4.1-1) unstable; urgency=medium
     1bitlbee (3.2.2-2) UNRELEASED; urgency=medium
    22
    33  * Fix copyright info (Closes: #764181)
    4   * "New" upstream release. Apologies for the delay.
    5   * Exclude .git not .bzr when building the source package.
    6 
    7  -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 03 Aug 2015 22:33:25 +0100
     4
     5 -- Wilmer van der Gaast <wilmer@gaast.net>  Fri, 17 Oct 2014 23:25:33 +0100
    86
    97bitlbee (3.2.2-1) unstable; urgency=medium
  • debian/source/options

    r3fbce97 r63cad66  
    1 --diff-ignore='(^|/)\.git'
     1--diff-ignore='(^|/)\.bzr'
  • doc/CHANGES

    r3fbce97 r63cad66  
    429429  officially be treated as case sensitive.
    430430- Fully stripping spaces from AIM screennames, this didn't happen completely
    431   which severely breaks the IRC protocol.
     431  which severly breaks the IRC protocol.
    432432- Removed all the yellow tape around daemon mode, it's pretty mature by now:
    433433  testing.bitlbee.org serves all (~30) SSL users from one daemon mode
     
    629629  some situations.
    630630- Outgoing MSN typing notifications are now understood correctly by the
    631   original MS Mac/Windows clients (again).
     631  orignal MS Mac/Windows clients (again).
    632632- Added "account add $protocol" to the documentation, got rid of a lot
    633633  of over-markup (i.e. overuse of bold-tags), reviewed some other parts.
  • doc/HACKING

    r3fbce97 r63cad66  
    1414calls and arguments where that seemed useful, etc.
    1515
    16 However, up to late in the 1.2 series, the IRC core was still spread across
     16However, up to late in the 1.2 series, the IRC core was still spread accross
    1717several files, mostly irc.c + irc_commands.c and pieces and bits in
    1818nogaim.c. If you're looking for a textbook example of layer violation, start
  • doc/README

    r3fbce97 r63cad66  
    88to set up the build system. If configure succeeds, run make to build BitlBee.
    99make install will move all the files to the right places.
    10 
    11 RUN MODES
    12 =========
    1310
    1411--- (Fork)Daemon mode
     
    9289==================
    9390
    94 The configure script is may not work very well with some non-bash shells (but
    95 dash is supported), so if you experience problems, make sure you use bash to
    96 run the script. Same for the Makefile, it only works well with GNU make. (gmake
    97 on most BSD systems)
     91Cygwin NOTE: You'll need a glib installation to run BitlBee. However, Cygwin
     92doesn't provide a glib package. You can download a binary tar.gz from:
     93<http://my.dreamwiz.com/jbdoll/>. When you installed it, BitlBee should work
     94fine. You'll probably like bitlbeed or xinetd to get it running on the
     95network.
     96
     97On some non-Linux systems the program still suffers from some random bugs.
     98Please do report them, we might be able to fix them if they're not too
     99mysterious.
     100
     101Also, the configure script is known to not work very well with non-Bash
     102shells, so if you experience problems, make sure you use bash to run the
     103script. Same for the Makefile, it only works well with GNU make. (gmake on
     104most BSD systems)
    98105
    99106If someone can tell us how to write Makefiles that work with both/all
     
    146153=============================
    147154
    148 BitlBee currently uses salted MD5 and RC4 to store the passwords. This means
    149 that people who somehow get their hands on your configuration files can't
    150 easily extract your passwords from them anymore.
     155There used to be a note here about the simple obfuscation method used to
     156make the passwords in the configuration files unreadable. However, BitlBee
     157now uses a better format (and real encryption (salted MD5 and RC4)) to store
     158the passwords. This means that people who somehow get their hands on your
     159configuration files can't easily extract your passwords from them anymore.
    151160
    152161However, once you log into the BitlBee server and send your password, an
    153162intruder with tcpdump can still read your passwords. This can't really be
    154 avoided, of course. So if you run a public server, it's most important that you
    155 don't give root access to people who like to play with tcpdump.
     163avoided, of course. The new format is a lot more reliable (because it can't
     164be cracked with just very basic crypto analysis anymore), but you still have
     165to be careful. The main extra protection offered by the new format is that
     166the files can only be cracked with some help from the user (by sending the
     167password at login time).
     168
     169So if you run a public server, it's most important that you don't give root
     170access to people who like to play with tcpdump. Also, it's a good idea to
     171delete all *.nicks/*.accounts files as soon as BitlBee converted them to the
     172new format (which happens as soon as the user logs in, it can't be done
     173automatically because it needs the password for that account). You won't
     174need them anymore (unless you want to switch back to an older BitlBee
     175version) and they only make it easier for others to crack your passwords.
     176
    156177
    157178LEGAL
     
    160181BitlBee is distributed under the GPL (GNU General Public License). See the
    161182file COPYING for this license.
     183
     184The MD5 algorithm code is licensed under the Aladdin license. This license
     185can be found in the files, to which this applies. The SHA1 algorithm code
     186is licensed under the Mozilla Public License, see http://www.mozilla.org/MPL/
     187for details.
    162188
    163189The Yahoo! library used by BitlBee is libyahoo2 <http://libyahoo2.sf.net/>,
  • doc/user-guide/Installation.xml

    r3fbce97 r63cad66  
    7373<para>
    7474By default, BitlBee runs as the user nobody. You might want
    75 to run it as a separate user (some computers run named or apache as nobody).
     75to run it as a seperate user (some computers run named or apache as nobody).
    7676</para>
    7777
  • doc/user-guide/commands.xml

    r3fbce97 r63cad66  
    182182                               
    183183                                <para>
    184                                         For more information about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
     184                                        For more infomation about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
    185185                                </para>
    186186                               
     
    240240                               
    241241                                <para>
    242                                         For more information about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
     242                                        For more infomation about a setting, see <emphasis>help set &lt;setting&gt;</emphasis>.
    243243                                </para>
    244244                               
     
    785785                        <para>
    786786                                Keep two things in mind: When not using Twitter, you <emphasis>must</emphasis> also disable the <emphasis>oauth</emphasis> setting as it currently only works with Twitter. If you're still having issues, make sure there is <emphasis>no</emphasis> slash at the end of the URL you enter here.
    787                         </para>
    788                 </description>
    789         </bitlbee-setting>
    790 
    791         <bitlbee-setting name="carbons" type="boolean" scope="account">
    792                 <default>true</default>
    793 
    794                 <description>
    795                         <para>
    796                                 Jabber specific. "Message carbons" (XEP-0280) is a server feature to get copies of outgoing messages sent from other clients connected to the same account. It's not widely supported by most public XMPP servers (easier if you host your own), but this will probably change in the next few years.
    797                         </para>
    798                         <para>
    799                                 This defaults to true, which will enable it if the server supports it, or fail silently if it's not. This setting only exists to allow disabling the feature if anyone considers it undesirable.
    800                         </para>
    801                         <para>
    802                                 See also the <emphasis>self_messages</emphasis> setting.
    803787                        </para>
    804788                </description>
     
    11091093                       
    11101094                        <para>
    1111                                 With modes "chat" and "many", you can send direct messages by /msg'ing your contacts directly. Incoming DMs are only fetched if the "stream" setting is on (default).
     1095                                With modes "chat" and "many", you can send direct messages by /msg'ing your contacts directly. Note, however, that incoming DMs are not fetched yet.
    11121096                        </para>
    11131097                       
     
    11741158                <description>
    11751159                        <para>
    1176                                 By default, BitlBee generates a nickname for every contact by taking its handle and chopping off everything after the @. In some cases, this gives very inconvenient nicknames. Some servers use internal identifiers, which are often just numbers.
     1160                                By default, BitlBee generates a nickname for every contact by taking its handle and chopping off everything after the @. In some cases, this gives very inconvenient nicknames. The Facebook XMPP server is a good example, as all Facebook XMPP handles are numeric.
    11771161                        </para>
    11781162
     
    11881172                <description>
    11891173                        <para>
    1190                                 This enables OAuth authentication for an IM account; right now the Twitter (working for Twitter only) and Jabber (for Google Talk only) module support it.
     1174                                This enables OAuth authentication for an IM account; right now the Twitter (working for Twitter only) and Jabber (for Google Talk, Facebook and MSN Messenger) module support it.
    11911175                        </para>
    11921176
     
    13401324        </bitlbee-setting>
    13411325
    1342         <bitlbee-setting name="proxy" type="string" scope="account">
    1343                 <default>&lt;local&gt;&lt;auto&gt;</default>
    1344 
    1345                 <description>
    1346                         <para>
    1347                                 A list of <emphasis>file transfer proxies</emphasis> for jabber. This isn't the connection proxy. Sorry, look in bitlbee.conf for those.
    1348                         </para>
    1349 
    1350                         <para>
    1351                                 It's a semicolon-separated list of items that can be either <emphasis>JID,HOST,PORT</emphasis> or two special values, <emphasis>&lt;local&gt;</emphasis> (to try a direct connection first) and <emphasis>&lt;auto&gt;</emphasis> (to try to discover a proxy). For example, "&lt;local&gt;;proxy.somewhere.org,123.123.123.123,7777".
    1352                         </para>
    1353                         <para>
    1354                                 The address should point to a SOCKS5 bytestreams server, usually provided by jabber servers. This is only used for sending files. Note that the host address might not match what DNS tells you, and the port isn't always the same.
    1355                         </para>
    1356                         <para>
    1357                                 The correct way to get a socks proxy host/port is a mystery, and the file transfer might fail anyway. Maybe just try using dropbox instead.
    1358                         </para>
    1359                 </description>
    1360         </bitlbee-setting>
    1361 
    13621326        <bitlbee-setting name="query_order" type="string" scope="global">
    13631327                <default>lifo</default>
     
    14201384        </bitlbee-setting>
    14211385
    1422         <bitlbee-setting name="self_messages" type="string" scope="global">
    1423                 <default>true</default>
    1424                 <possible-values>true, false, prefix, prefix_notice</possible-values>
    1425 
    1426                 <description>
    1427                         <para>
    1428                                 Change this setting to customize how (or whether) to show self-messages, which are messages sent by yourself from other locations (for example, mobile clients), for IM protocols that support it.
    1429                         </para>
    1430 
    1431                         <para>
    1432                                 When this is set to "true", it will send those messages in the "standard" way, which is a PRIVMSG with source and target fields swapped.
    1433                         </para>
    1434                        
    1435                         <para>
    1436                                 Since this isn't very well supported by some clients (the messages might appear in the wrong window), you can set it to "prefix" to show them as a normal message prefixed with "-> ", or use "prefix_notice" which is the same thing but with a NOTICE instead.
    1437                         </para>
    1438 
    1439                         <para>
    1440                                 You can also set it to "false" to disable these messages completely.
    1441                         </para>
    1442 
    1443                         <para>
    1444                                 This setting only applies to private messages. Self messages in groupchats are always shown, since they haven't caused issues in any clients so far.
    1445                         </para>
    1446 
    1447                         <para>
    1448                                 More information: <emphasis>https://wiki.bitlbee.org/SelfMessages</emphasis>
    1449                         </para>
    1450                 </description>
    1451         </bitlbee-setting>
    1452 
    14531386        <bitlbee-setting name="server" type="string" scope="account">
    14541387                <description>
     
    14841417
    14851418        <bitlbee-setting name="show_users" type="string" scope="channel">
    1486                 <default>online+,special%,away</default>
     1419                <default>online+,away</default>
    14871420
    14881421                <description>
     
    14911424                                and any modes they should have. The following statuses are currently
    14921425                                recognised: <emphasis>online</emphasis> (i.e. available, not
    1493                                 away), <emphasis>special</emphasis>, <emphasis>away</emphasis>,
    1494                                 and <emphasis>offline</emphasis>.
     1426                                away), <emphasis>away</emphasis>, and <emphasis>offline</emphasis>.
    14951427                        </para>
    14961428                       
     
    14981430                                If a status is followed by a valid channel mode character
    14991431                                (@, % or +), it will be given to users with that status.
    1500                                 For example, <emphasis>online@,special%,away+,offline</emphasis>
    1501                                 will show all users in the channel. Online people will
     1432                                For example, <emphasis>online@,away+,offline</emphasis> will
     1433                                show all users in the channel. Online people will
    15021434                                have +o, people who are online but away will have +v,
    15031435                                and others will have no special modes.
     
    19591891
    19601892                        <description>
    1961                                 <para>Rejects all incoming (not already transferring) file transfers. Since you probably have only one incoming transfer at a time, no id is necessary. Or is it?</para>
     1893                                <para>Rejects all incoming (not already transferring) file transfers. Since you probably have only one incoming transfer at a time, no id is neccessary. Or is it?</para>
    19621894                        </description>
    19631895
  • doc/user-guide/misc.xml

    r3fbce97 r63cad66  
    9090
    9191<para>
    92 Away states have different names across different protocols. BitlBee will try to pick the best available option for every connection:
     92Away states have different names accross different protocols. BitlBee will try to pick the best available option for every connection:
    9393</para>
    9494
     
    146146
    147147<para>
    148 Control channels are where you see your contacts. By default, you will have one control channel called &amp;bitlbee, containing all your contacts. But you can create more, if you want, and divide your contact list across several channels.
     148Control channels are where you see your contacts. By default, you will have one control channel called &amp;bitlbee, containing all your contacts. But you can create more, if you want, and divide your contact list accross several channels.
    149149</para>
    150150
  • doc/user-guide/quickstart.xml

    r3fbce97 r63cad66  
    1111
    1212<para>
    13 You need to register so that all your IM settings (passwords, contacts, etc) can be saved on the BitlBee server. It's important that you pick a good password so no one else can access your account. Register with this password using the <emphasis>register</emphasis> command: <emphasis>register &lt;password&gt;</emphasis> (without the brackets!).
     13You need register so that all your IM settings (passwords, contacts, etc) can be saved on the BitlBee server. It's important that you pick a good password so no one else can access your account. Register with this password using the <emphasis>register</emphasis> command: <emphasis>register &lt;password&gt;</emphasis> (without the brackets!).
    1414</para>
    1515
  • help.c

    r3fbce97 r63cad66  
    105105        h = *help;
    106106        while (h) {
    107                 if (h->fd == -1) {
    108                         g_free(h->offset.mem_offset);
    109                 } else if (h->fd != last_fd) {
     107                if (h->fd != last_fd) {
    110108                        close(h->fd);
    111109                        last_fd = h->fd;
     
    148146                        if (lseek(h->fd, h->offset.file_offset, SEEK_SET) == -1 ||
    149147                            read(h->fd, s, h->length) != h->length) {
    150                                 g_free(s);
    151148                                return NULL;
    152149                        }
  • ipc.c

    r3fbce97 r63cad66  
    590590                                }
    591591
    592                                 memcpy(recv_fd, CMSG_DATA(cmsg), sizeof(int));
     592                                *recv_fd = *(int *) CMSG_DATA(cmsg);
    593593                                /*
    594594                                fprintf( stderr, "pid %d received fd %d\n", (int) getpid(), *recv_fd );
     
    758758        cmsg->cmsg_type = SCM_RIGHTS;
    759759        cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
    760         memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(int));
     760        *(int *) CMSG_DATA(cmsg) = send_fd;
    761761        msg.msg_controllen = cmsg->cmsg_len;
    762762#endif
  • irc.c

    r3fbce97 r63cad66  
    129129        s = set_add(&b->set, "show_offline", "false", set_eval_bw_compat, irc);
    130130        s->flags |= SET_HIDDEN;
    131         s = set_add(&b->set, "self_messages", "true", set_eval_self_messages, irc);
    132131        s = set_add(&b->set, "simulate_netsplit", "true", set_eval_bool, irc);
    133132        s = set_add(&b->set, "timezone", "local", set_eval_timezone, irc);
     
    154153        set_eval_charset(set_find(&b->set, "charset"), set_getstr(&b->set, "charset"));
    155154
    156         irc_write(irc, ":%s NOTICE * :%s", irc->root->host, "BitlBee-IRCd initialized, please go on");
     155        irc_write(irc, ":%s NOTICE AUTH :%s", irc->root->host, "BitlBee-IRCd initialized, please go on");
    157156        if (isatty(irc->fd)) {
    158                 irc_write(irc, ":%s NOTICE * :%s", irc->root->host,
     157                irc_write(irc, ":%s NOTICE AUTH :%s", irc->root->host,
    159158                          "If you read this, you most likely accidentally "
    160159                          "started BitlBee in inetd mode on the command line. "
     
    381380                                                conv = NULL;
    382381                                        } else {
    383                                                 irc_write(irc, ":%s NOTICE * :%s", irc->root->host,
     382                                                irc_write(irc, ":%s NOTICE AUTH :%s", irc->root->host,
    384383                                                          "Warning: invalid characters received at login time.");
    385384
     
    728727int irc_check_login(irc_t *irc)
    729728{
    730         if (irc->user->user && irc->user->nick && !(irc->status & USTATUS_CAP_PENDING)) {
     729        if (irc->user->user && irc->user->nick) {
    731730                if (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED)) {
    732731                        irc_send_num(irc, 464, ":This server is password-protected.");
  • irc.h

    r3fbce97 r63cad66  
    4949        USTATUS_SHUTDOWN = 8,   /* Now used to indicate we're shutting down.
    5050                                   Currently just blocks irc_vawrite(). */
    51         USTATUS_CAP_PENDING = 16,
    52         USTATUS_SASL_PLAIN_PENDING = 32,
    5351
    5452        /* Not really status stuff, but other kinds of flags: For slightly
     
    6765} irc_status_t;
    6866
    69 typedef enum {
    70         CAP_SASL = (1 << 0),
    71         CAP_MULTI_PREFIX = (1 << 1),
    72         CAP_EXTENDED_JOIN = (1 << 2),
    73         CAP_AWAY_NOTIFY = (1 << 3),
    74         CAP_USERHOST_IN_NAMES = (1 << 4),
    75 } irc_cap_flag_t;
    76 
    7767struct irc_user;
    7868
     
    112102
    113103        struct bee *b;
    114         guint32 caps;
    115104} irc_t;
    116105
     
    313302gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name);
    314303void irc_channel_update_ops(irc_channel_t *ic, char *value);
    315 char irc_channel_user_get_prefix(irc_channel_user_t *icu);
    316304char *set_eval_irc_channel_ops(struct set *set, char *value);
    317305gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu);
     
    343331                                     irc_channel_user_flags_t old_flags, irc_channel_user_flags_t new_flags);
    344332void irc_send_invite(irc_user_t *iu, irc_channel_t *ic);
    345 void irc_send_cap(irc_t *irc, char *subcommand, char *body);
    346 void irc_send_away_notify(irc_user_t *iu);
    347333
    348334/* irc_user.c */
     
    358344char *set_eval_timezone(struct set *set, char *value);
    359345char *irc_format_timestamp(irc_t *irc, time_t msg_ts);
    360 char *set_eval_self_messages(struct set *set, char *value);
    361346
    362347/* irc_im.c */
     
    364349void bee_irc_user_nick_reset(irc_user_t *iu);
    365350
    366 /* irc_cap.c */
    367 void irc_cmd_cap(irc_t *irc, char **cmd);
    368 
    369351#endif
  • irc_channel.c

    r3fbce97 r63cad66  
    213213        }
    214214
    215         /* Skip the free/init if nothing is being changed */
    216         if (ic->f == new) {
    217                 return value;
    218         }
    219 
    220215        /* TODO: Return values. */
    221216        if (ic->f && ic->f->_free) {
     
    260255
    261256        if (!(icu = irc_channel_has_user(ic, iu))) {
    262                 if (iu == ic->irc->user && type == IRC_CDU_KICK) {
    263                         /* an error happened before joining, inform the client with a numeric */
    264                         irc_send_num(ic->irc, 403, "%s :Error joining channel (check control channel?)", ic->name);
    265                 }
    266257                return 0;
    267258        }
     
    436427                          changes);
    437428        }
    438 }
    439 
    440 char irc_channel_user_get_prefix(irc_channel_user_t *icu)
    441 {
    442         if (icu->flags & IRC_CHANNEL_USER_OP) {
    443                 return '@';
    444         } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) {
    445                 return '%';
    446         } else if (icu->flags & IRC_CHANNEL_USER_VOICE) {
    447                 return '+';
    448         }
    449         return 0;
    450429}
    451430
     
    614593
    615594        translit_name = g_convert_with_fallback(hint, -1, "ASCII//TRANSLIT", "UTF-8", "", NULL, &bytes_written, NULL);
    616 
    617         if (!translit_name) {
    618                 /* Same thing as in nick_gen() in nick.c, try again without //TRANSLIT */
    619                 translit_name = g_convert_with_fallback(hint, -1, "ASCII", "UTF-8", "", NULL, &bytes_written, NULL);
    620         }
    621 
    622         if (!translit_name) {
    623                 return NULL;
    624         }
    625 
    626595        if (bytes_written > MAX_NICK_LENGTH) {
    627596                translit_name[MAX_NICK_LENGTH] = '\0';
  • irc_commands.c

    r3fbce97 r63cad66  
    2828#include "help.h"
    2929#include "ipc.h"
    30 #include "base64.h"
    3130
    3231static void irc_cmd_pass(irc_t *irc, char **cmd)
     
    5655                irc_setpass(irc, cmd[1]);
    5756                irc_check_login(irc);
    58         }
    59 }
    60 
    61 static gboolean irc_sasl_plain_parse(char *input, char **user, char **pass)
    62 {
    63         int i, part, len;
    64         guint8 *decoded;
    65         char *parts[3];
    66 
    67         /* bitlbee's base64_decode wrapper adds an extra null terminator at the end */
    68         len = base64_decode(input, &decoded);
    69 
    70         /* this loop splits the decoded string into the parts array, like this:
    71            "username\0username\0password" -> {"username", "username", "password"} */
    72 
    73         for (i = 0, part = 0; i < len && part < 3; part++) {
    74                 /* set each of parts[] to point to the beginning of a string */
    75                 parts[part] = (char *) decoded + i;
    76 
    77                 /* move the cursor forward to the next null terminator*/
    78                 i += strlen(parts[part]) + 1;
    79         }
    80 
    81         /* sanity checks */
    82         if (part != 3 || i != (len + 1) || (parts[0][0] && strcmp(parts[0], parts[1]) != 0)) {
    83                 g_free(decoded);
    84                 return FALSE;
    85         } else {
    86                 *user = g_strdup(parts[1]);
    87                 *pass = g_strdup(parts[2]);
    88                 g_free(decoded);
    89                 return TRUE;
    90         }
    91 }
    92 
    93 static gboolean irc_sasl_check_pass(irc_t *irc, char *user, char *pass)
    94 {
    95         storage_status_t status;
    96 
    97         /* just check the password here to be able to reply with useful numerics
    98          * the actual identification will be handled later */
    99         status = storage_check_pass(user, pass);
    100 
    101         if (status == STORAGE_OK) {
    102                 if (!irc->user->nick) {
    103                         /* set the nick here so we have it for the following numeric */
    104                         irc->user->nick = g_strdup(user);
    105                 }
    106                 irc_send_num(irc, 903, ":Password accepted");
    107                 return TRUE;
    108 
    109         } else if (status == STORAGE_INVALID_PASSWORD) {
    110                 irc_send_num(irc, 904, ":Incorrect password");
    111         } else if (status == STORAGE_NO_SUCH_USER) {
    112                 irc_send_num(irc, 904, ":The nick is (probably) not registered");
    113         } else {
    114                 irc_send_num(irc, 904, ":Unknown SASL authentication error");
    115         }
    116 
    117         return FALSE;
    118 }
    119 
    120 static void irc_cmd_authenticate(irc_t *irc, char **cmd)
    121 {
    122         /* require the CAP to be enabled, and don't allow authentication before server password */
    123         if (!(irc->caps & CAP_SASL) ||
    124             (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED))) {
    125                 return;
    126         }
    127 
    128         if (irc->status & USTATUS_SASL_PLAIN_PENDING) {
    129                 char *user, *pass;
    130 
    131                 irc->status &= ~USTATUS_SASL_PLAIN_PENDING;
    132 
    133                 if (!irc_sasl_plain_parse(cmd[1], &user, &pass)) {
    134                         irc_send_num(irc, 904, ":SASL authentication failed");
    135                         return;
    136                 }
    137 
    138                 /* let's not support the nick != user case
    139                  * if NICK is received after SASL, it will just fail after registration */
    140                 if (user && irc->user->nick && strcmp(user, irc->user->nick) != 0) {
    141                         irc_send_num(irc, 902, ":Your SASL username does not match your nickname");
    142 
    143                 } else if (irc_sasl_check_pass(irc, user, pass)) {
    144                         /* and here we do the same thing as the PASS command*/
    145                         if (irc->status & USTATUS_LOGGED_IN) {
    146                                 char *send_cmd[] = { "identify", pass, NULL };
    147                                 root_command(irc, send_cmd);
    148                         } else {
    149                                 /* no check_login here - wait for CAP END */
    150                                 irc_setpass(irc, pass);
    151                         }
    152                 }
    153 
    154                 g_free(user);
    155                 g_free(pass);
    156 
    157         } else if (irc->status & USTATUS_IDENTIFIED) {
    158                 irc_send_num(irc, 907, ":You have already authenticated");
    159 
    160         } else if (strcmp(cmd[1], "*") == 0) {
    161                 irc_send_num(irc, 906, ":SASL authentication aborted");
    162                 irc->status &= ~USTATUS_SASL_PLAIN_PENDING;
    163 
    164         } else if (g_strcasecmp(cmd[1], "PLAIN") == 0) {
    165                 irc_write(irc, "AUTHENTICATE +");
    166                 irc->status |= USTATUS_SASL_PLAIN_PENDING;
    167 
    168         } else {
    169                 irc_send_num(irc, 908, "PLAIN :is the available SASL mechanism");
    170                 irc_send_num(irc, 904, ":SASL authentication failed");
    171                 irc->status &= ~USTATUS_SASL_PLAIN_PENDING;
    17257        }
    17358}
     
    19883                        irc->status &= ~USTATUS_IDENTIFIED;
    19984                        irc_umode_set(irc, "-R", 1);
    200 
    201                         if (irc->caps & CAP_SASL) {
    202                                 irc_send_num(irc, 901, "%s!%s@%s :You are now logged out",
    203                                         irc->user->nick, irc->user->user, irc->user->host);
    204                         }
    205 
    20685                        irc_rootmsg(irc, "Changing nicks resets your identify status. "
    20786                                    "Re-identify or register a new account if you want "
     
    806685
    807686static const command_t irc_commands[] = {
    808         { "cap",         1, irc_cmd_cap,         0 },
    809687        { "pass",        1, irc_cmd_pass,        0 },
    810688        { "user",        4, irc_cmd_user,        IRC_CMD_PRE_LOGIN },
     
    843721        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    844722        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    845         { "authenticate", 1, irc_cmd_authenticate, 0 },
    846723        { NULL }
    847724};
  • irc_im.c

    r3fbce97 r63cad66  
    8484        }
    8585
    86         /* Sanitize */
    87         str_reject_chars(iu->user, " ", '_');
    88         str_reject_chars(iu->host, " ", '_');
     86        while ((s = strchr(iu->user, ' '))) {
     87                *s = '_';
     88        }
    8989
    9090        if (bu->flags & BEE_USER_LOCAL) {
     
    118118        if (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) {
    119119                iu->flags |= IRC_USER_AWAY;
    120         }
    121 
    122         if ((irc->caps & CAP_AWAY_NOTIFY) &&
    123             ((bu->flags & BEE_USER_AWAY) != (old->flags & BEE_USER_AWAY) ||
    124              (bu->flags & BEE_USER_ONLINE) != (old->flags & BEE_USER_ONLINE))) {
    125                 irc_send_away_notify(iu);
    126120        }
    127121
     
    207201}
    208202
    209 static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, guint32 flags, time_t sent_at)
     203static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at)
    210204{
    211205        irc_t *irc = bee->ui_data;
    212206        irc_user_t *iu = (irc_user_t *) bu->ui_data;
    213         irc_user_t *src_iu = iu;
    214         irc_user_t *dst_iu = irc->user;
    215207        const char *dst;
    216208        char *prefix = NULL;
    217209        char *wrapped, *ts = NULL;
    218210        char *msg = g_strdup(msg_);
    219         char *message_type = "PRIVMSG";
    220211        GSList *l;
    221212
     
    225216
    226217        dst = irc_user_msgdest(iu);
    227 
    228         if (flags & OPT_SELFMESSAGE) {
    229                 char *setting = set_getstr(&irc->b->set, "self_messages");
    230 
    231                 if (is_bool(setting)) {
    232                         if (bool2int(setting)) {
    233                                 /* set to true, send it with src/dst flipped */
    234                                
    235                                 dst_iu = iu;
    236                                 src_iu = irc->user;
    237 
    238                                 if (dst == irc->user->nick) {
    239                                         dst = dst_iu->nick;
    240                                 }
    241                         } else {
    242                                 /* set to false, skip the message completely */
    243                                 goto cleanup;
    244                         }
    245                 } else if (g_strncasecmp(setting, "prefix", 6) == 0) {
    246                         /* third state, prefix, loosely imitates the znc privmsg_prefix module */
    247 
    248                         g_free(msg);
    249                         if (g_strncasecmp(msg_, "/me ", 4) == 0) {
    250                                 msg = g_strdup_printf("/me -> %s", msg_ + 4);
    251                         } else {
    252                                 msg = g_strdup_printf("-> %s", msg_);
    253                         }
    254 
    255                         if (g_strcasecmp(setting, "prefix_notice") == 0) {
    256                                 message_type = "NOTICE";
    257                         }
    258                 }
    259 
    260         }
    261 
    262         if (dst != dst_iu->nick) {
    263                 /* if not messaging directly (control channel), call user by name */
    264                 prefix = g_strdup_printf("%s%s%s", dst_iu->nick, set_getstr(&bee->set, "to_char"), ts ? : "");
     218        if (dst != irc->user->nick) {
     219                /* if not messaging directly, call user by name */
     220                prefix = g_strdup_printf("%s%s%s", irc->user->nick, set_getstr(&bee->set, "to_char"), ts ? : "");
    265221        } else {
    266222                prefix = ts;
     
    293249
    294250        wrapped = word_wrap(msg, 425);
    295         irc_send_msg(src_iu, message_type, dst, wrapped, prefix);
     251        irc_send_msg(iu, "PRIVMSG", dst, wrapped, prefix);
    296252        g_free(wrapped);
    297253
     
    304260}
    305261
    306 static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, guint32 flags)
     262static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, uint32_t flags)
    307263{
    308264        irc_t *irc = (irc_t *) bee->ui_data;
     
    661617}
    662618
    663 static gboolean bee_irc_chat_msg(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at)
     619static gboolean bee_irc_chat_msg(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at)
    664620{
    665621        irc_t *irc = bee->ui_data;
    666         irc_user_t *iu = flags & OPT_SELFMESSAGE ? irc->user : bu->ui_data;
     622        irc_user_t *iu = bu->ui_data;
    667623        irc_channel_t *ic = c->ui_data;
    668624        char *wrapped, *ts = NULL;
     
    698654}
    699655
    700 static gboolean bee_irc_chat_remove_user(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *reason)
     656static gboolean bee_irc_chat_remove_user(bee_t *bee, struct groupchat *c, bee_user_t *bu)
    701657{
    702658        irc_t *irc = bee->ui_data;
     
    710666           using imcb_chat_free() and the channel was IRC_CHANNEL_TEMP, we get into
    711667           a broken state around here. */
    712         irc_channel_del_user(ic, bu == bee->user ? irc->user : bu->ui_data, IRC_CDU_PART, reason);
     668        irc_channel_del_user(ic, bu == bee->user ? irc->user : bu->ui_data, IRC_CDU_PART, NULL);
    713669
    714670        return TRUE;
     
    883839            acc->prpl->chat_join) {
    884840                char *nick;
    885                 struct groupchat *gc;
    886841
    887842                if (!(nick = set_getstr(&ic->set, "nick"))) {
     
    890845
    891846                ic->flags |= IRC_CHANNEL_CHAT_PICKME;
    892                 gc = acc->prpl->chat_join(acc->ic, room, nick, NULL, &ic->set);
     847                acc->prpl->chat_join(acc->ic, room, nick, NULL, &ic->set);
    893848                ic->flags &= ~IRC_CHANNEL_CHAT_PICKME;
    894 
    895                 if (!gc) {
    896                         irc_send_num(ic->irc, 403, "%s :Error joining channel (check control channel?)", ic->name);
    897                 }
    898849
    899850                return FALSE;
     
    912863        }
    913864
    914         if (!(ic->flags & IRC_CHANNEL_TEMP)) {
    915                 /* Remove the reference.
    916                  * We only need it for temp channels that are being freed */
    917                 ic->data = NULL;
    918         }
     865        /* Remove the reference. We don't need it anymore. */
     866        ic->data = NULL;
    919867
    920868        return TRUE;
     
    11071055                df->proto_finished = TRUE;
    11081056        }
    1109 }
    1110 
    1111 static void bee_irc_log(bee_t *bee, const char *tag, const char *msg)
    1112 {
    1113         irc_t *irc = (irc_t *) bee->ui_data;
    1114 
    1115         irc_rootmsg(irc, "%s - %s", tag, msg);
    11161057}
    11171058
     
    11441085        bee_irc_ft_close,
    11451086        bee_irc_ft_finished,
    1146 
    1147         bee_irc_log,
    11481087};
  • irc_send.c

    r3fbce97 r63cad66  
    172172        irc_t *irc = ic->irc;
    173173
    174         if (irc->caps & CAP_EXTENDED_JOIN) {
    175                 irc_write(irc, ":%s!%s@%s JOIN %s * :%s", iu->nick, iu->user, iu->host, ic->name, iu->fullname);
    176         } else {
    177                 irc_write(irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name);
    178         }
     174        irc_write(irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name);
    179175
    180176        if (iu == irc->user) {
     
    202198}
    203199
    204 #define IRC_NAMES_LEN 385
    205 
    206200void irc_send_names(irc_channel_t *ic)
    207201{
    208202        GSList *l;
    209         GString *namelist = g_string_sized_new(IRC_NAMES_LEN);
    210         gboolean uhnames = (ic->irc->caps & CAP_USERHOST_IN_NAMES);
     203        char namelist[385] = "";
    211204
    212205        /* RFCs say there is no error reply allowed on NAMES, so when the
     
    215208                irc_channel_user_t *icu = l->data;
    216209                irc_user_t *iu = icu->iu;
    217                 size_t extra_len = strlen(iu->nick);
    218                 char prefix;
    219 
    220                 if (uhnames) {
    221                         extra_len += strlen(iu->user) + strlen(iu->host) + 2;
    222                 }
    223 
    224                 if (namelist->len + extra_len > IRC_NAMES_LEN - 4) {
    225                         irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist->str);
    226                         g_string_truncate(namelist, 0);
    227                 }
    228 
    229                 if ((prefix = irc_channel_user_get_prefix(icu))) {
    230                         g_string_append_c(namelist, prefix);
    231                 }
    232 
    233                 if (uhnames) {
    234                         g_string_append_printf(namelist, "%s!%s@%s ", iu->nick, iu->user, iu->host);
    235                 } else {
    236                         g_string_append(namelist, iu->nick);
    237                         g_string_append_c(namelist, ' ');
    238                 }
    239         }
    240 
    241         if (namelist->len) {
    242                 irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist->str);
     210
     211                if (strlen(namelist) + strlen(iu->nick) > sizeof(namelist) - 4) {
     212                        irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist);
     213                        *namelist = 0;
     214                }
     215
     216                if (icu->flags & IRC_CHANNEL_USER_OP) {
     217                        strcat(namelist, "@");
     218                } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) {
     219                        strcat(namelist, "%");
     220                } else if (icu->flags & IRC_CHANNEL_USER_VOICE) {
     221                        strcat(namelist, "+");
     222                }
     223
     224                strcat(namelist, iu->nick);
     225                strcat(namelist, " ");
     226        }
     227
     228        if (*namelist) {
     229                irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist);
    243230        }
    244231
    245232        irc_send_num(ic->irc, 366, "%s :End of /NAMES list", ic->name);
    246 
    247         g_string_free(namelist, TRUE);
    248233}
    249234
     
    264249}
    265250
    266 /* msg1 and msg2 are output parameters. If msg2 is non-null, msg1 is guaranteed to be non-null too.
    267    The idea is to defer the formatting of "$msg1 ($msg2)" to later calls to avoid a g_strdup_printf() here. */
    268 static void get_status_message(bee_user_t *bu, char **msg1, char **msg2)
    269 {
    270         *msg1 = NULL;
    271         *msg2 = NULL;
    272 
    273         if (!(bu->flags & BEE_USER_ONLINE)) {
    274                 *msg1 = "User is offline";
    275 
    276         } else if ((bu->status && *bu->status) ||
    277                    (bu->status_msg && *bu->status_msg)) {
    278 
    279                 if (bu->status && bu->status_msg) {
    280                         *msg1 = bu->status;
    281                         *msg2 = bu->status_msg;
    282                 } else {
    283                         *msg1 = bu->status ? : bu->status_msg;
    284                 }
    285         }
    286 
    287         if (*msg1 && !**msg1) {
    288                 *msg1 = (bu->flags & BEE_USER_AWAY) ? "Away" : NULL;
    289         }
    290 }
    291 
    292251void irc_send_whois(irc_user_t *iu)
    293252{
     
    299258        if (iu->bu) {
    300259                bee_user_t *bu = iu->bu;
    301                 char *msg1, *msg2;
    302                 int num;
    303260
    304261                irc_send_num(irc, 312, "%s %s.%s :%s network", iu->nick, bu->ic->acc->user,
     
    306263                             bu->ic->acc->prpl->name);
    307264
    308                 num = (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) ? 301 : 320;
    309 
    310                 get_status_message(bu, &msg1, &msg2);
    311 
    312                 if (msg1 && msg2) {
    313                         irc_send_num(irc, num, "%s :%s (%s)", iu->nick, msg1, msg2);
    314                 } else if (msg1) {
    315                         irc_send_num(irc, num, "%s :%s", iu->nick, msg1);
     265                if ((bu->status && *bu->status) ||
     266                    (bu->status_msg && *bu->status_msg)) {
     267                        int num = bu->flags & BEE_USER_AWAY ? 301 : 320;
     268
     269                        if (bu->status && bu->status_msg) {
     270                                irc_send_num(irc, num, "%s :%s (%s)", iu->nick, bu->status, bu->status_msg);
     271                        } else {
     272                                irc_send_num(irc, num, "%s :%s", iu->nick, bu->status ? : bu->status_msg);
     273                        }
     274                } else if (!(bu->flags & BEE_USER_ONLINE)) {
     275                        irc_send_num(irc, 301, "%s :%s", iu->nick, "User is offline");
    316276                }
    317277
     
    334294
    335295        while (l) {
    336                 irc_user_t *iu;
    337 
    338                 /* Null terminated string with three chars, respectively:
    339                  * { <H|G>, <@|%|+|\0>, \0 } */
    340                 char status_prefix[3] = {0};
    341 
     296                irc_user_t *iu = l->data;
    342297                if (is_channel) {
    343                         irc_channel_user_t *icu = l->data;
    344                         status_prefix[1] = irc_channel_user_get_prefix(icu);
    345                         iu = icu->iu;
    346                 } else {
    347                         iu = l->data;
    348                 }
    349 
    350                 /* rfc1459 doesn't mention this: G means gone, H means here */
    351                 status_prefix[0] = iu->flags & IRC_USER_AWAY ? 'G' : 'H';
    352 
    353                 irc_send_num(irc, 352, "%s %s %s %s %s %s :0 %s",
     298                        iu = ((irc_channel_user_t *) iu)->iu;
     299                }
     300                /* TODO(wilmer): Restore away/channel information here */
     301                irc_send_num(irc, 352, "%s %s %s %s %s %c :0 %s",
    354302                             is_channel ? channel : "*", iu->user, iu->host, irc->root->host,
    355                              iu->nick, status_prefix, iu->fullname);
     303                             iu->nick, iu->flags & IRC_USER_AWAY ? 'G' : 'H',
     304                             iu->fullname);
    356305                l = l->next;
    357306        }
     
    479428                  iu->nick, iu->user, iu->host, irc->user->nick, ic->name);
    480429}
    481 
    482 void irc_send_cap(irc_t *irc, char *subcommand, char *body)
    483 {
    484         char *nick = irc->user->nick ? : "*";
    485 
    486         irc_write(irc, ":%s CAP %s %s :%s", irc->root->host, nick, subcommand, body);
    487 }
    488 
    489 void irc_send_away_notify(irc_user_t *iu)
    490 {
    491         bee_user_t *bu = iu->bu;
    492 
    493         if (!bu) {
    494                 return;
    495         }
    496 
    497         if (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) {
    498                 char *msg1, *msg2;
    499 
    500                 get_status_message(bu, &msg1, &msg2);
    501 
    502                 if (msg2) {
    503                         irc_write(iu->irc, ":%s!%s@%s AWAY :%s (%s)", iu->nick, iu->user, iu->host, msg1, msg2);
    504                 } else {
    505                         irc_write(iu->irc, ":%s!%s@%s AWAY :%s", iu->nick, iu->user, iu->host, msg1);
    506                 }
    507         } else {
    508                 irc_write(iu->irc, ":%s!%s@%s AWAY", iu->nick, iu->user, iu->host);
    509         }
    510 }
    511 
  • irc_util.c

    r3fbce97 r63cad66  
    119119        }
    120120}
    121 
    122 
    123 char *set_eval_self_messages(set_t *set, char *value)
    124 {
    125         if (is_bool(value) ||
    126             g_strcasecmp(value, "prefix") == 0 ||
    127             g_strcasecmp(value, "prefix_notice") == 0) {
    128                 return value;
    129         } else {
    130                 return SET_INVALID;
    131         }
    132 }
  • lib/http_client.c

    r3fbce97 r63cad66  
    162162        }
    163163
    164         if (req->func != NULL) {
    165                 req->func(req);
    166         }
     164        req->func(req);
    167165        http_free(req);
    168166        return FALSE;
     
    301299        }
    302300
    303         if (req->func != NULL) {
    304                 req->func(req);
    305         }
     301        req->func(req);
    306302        http_free(req);
    307303        return FALSE;
     
    416412        }
    417413
    418         if ((req->flags & HTTPC_STREAMING) && req->reply_body && req->func != NULL) {
     414        if ((req->flags & HTTPC_STREAMING) && req->reply_body) {
    419415                req->func(req);
    420416        }
     
    700696                ssl_disconnect(req->ssl);
    701697        } else {
    702                 proxy_disconnect(req->fd);
     698                closesocket(req->fd);
    703699        }
    704700
  • lib/ini.c

    r3fbce97 r63cad66  
    2828ini_t *ini_open(char *file)
    2929{
    30         int fd = -1;
     30        int fd;
    3131        ini_t *ini = NULL;
    3232        struct stat fi;
    3333
    34         if (file && (fd = open(file, O_RDONLY)) != -1 &&
     34        if ((fd = open(file, O_RDONLY)) != -1 &&
    3535            fstat(fd, &fi) == 0 &&
    3636            fi.st_size <= 16384 &&
  • lib/misc.c

    r3fbce97 r63cad66  
    187187                                } else if (g_strncasecmp(cs + 1, "br", taglen) == 0) {
    188188                                        *(s++) = '\n';
    189                                 } else if (g_strncasecmp(cs + 1, "br/", taglen) == 0) {
    190                                         *(s++) = '\n';
    191                                 } else if (g_strncasecmp(cs + 1, "br /", taglen) == 0) {
    192                                         *(s++) = '\n';
    193189                                }
    194190                                in++;
     
    299295
    300296/* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */
    301 /* This function is safe, but make sure you call it safely as well! */
     297/* This fuction is safe, but make sure you call it safely as well! */
    302298void http_encode(char *s)
    303299{
     
    771767}
    772768
    773 /* Filters all the characters in 'blacklist' replacing them with 'replacement'.
    774  * Modifies the string in-place and returns the string itself.
    775  * For the opposite, use g_strcanon() */
    776 char *str_reject_chars(char *string, const char *reject, char replacement)
    777 {
    778         char *c = string;
    779 
    780         while (*c) {
    781                 c += strcspn(c, reject);
    782                 if (*c) {
    783                         *c = replacement;
    784                 }
    785         }
    786 
    787         return string;
    788 }
  • lib/misc.h

    r3fbce97 r63cad66  
    150150G_MODULE_EXPORT int truncate_utf8(char *string, int maxlen);
    151151G_MODULE_EXPORT gboolean parse_int64(char *string, int base, guint64 *number);
    152 G_MODULE_EXPORT char *str_reject_chars(char *string, const char *reject, char replacement);
    153152
    154153#endif
  • lib/proxy.c

    r3fbce97 r63cad66  
    5151#endif
    5252
    53 static GHashTable *phb_hash = NULL;
    54 
    5553struct PHB {
    5654        b_event_handler func, proxy_func;
     
    6361};
    6462
    65 typedef int (*proxy_connect_func)(const char *host, unsigned short port_, struct PHB *phb);
    66 
    6763static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb);
    6864
    69 static gboolean phb_free(struct PHB *phb, gboolean success)
    70 {
    71         g_hash_table_remove(phb_hash, &phb->fd);
    72 
    73         if (!success) {
    74                 if (phb->fd > 0) {
    75                         closesocket(phb->fd);
    76                 }
    77                 if (phb->func) {
    78                         phb->func(phb->data, -1, B_EV_IO_READ);
    79                 }
    80         }
    81         if (phb->gai) {
    82                 freeaddrinfo(phb->gai);
    83         }
     65static gboolean phb_close(struct PHB *phb)
     66{
     67        close(phb->fd);
     68        phb->func(phb->data, -1, B_EV_IO_READ);
    8469        g_free(phb->host);
    8570        g_free(phb);
     
    10489                                dup2(new_fd, source);
    10590                                closesocket(new_fd);
    106                                 phb->fd = source;
    10791                                phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb);
    10892                                return FALSE;
     
    117101
    118102        freeaddrinfo(phb->gai);
    119         phb->gai = NULL;
    120 
    121103        b_event_remove(phb->inpa);
    122104        phb->inpa = 0;
    123 
    124105        if (phb->proxy_func) {
    125106                phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);
    126107        } else {
    127108                phb->func(phb->data, source, B_EV_IO_READ);
    128                 phb_free(phb, TRUE);
     109                g_free(phb);
    129110        }
    130111
     
    190171
    191172        if (fd < 0 && host) {
    192                 phb_free(phb, TRUE);
     173                g_free(phb);
    193174        }
    194175
     
    223204            (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) {
    224205                phb->func(phb->data, source, B_EV_IO_READ);
    225                 return phb_free(phb, TRUE);
    226         }
    227 
    228         return phb_free(phb, FALSE);
     206                g_free(phb->host);
     207                g_free(phb);
     208                return FALSE;
     209        }
     210
     211        return phb_close(phb);
    229212}
    230213
     
    241224        len = sizeof(error);
    242225        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    243                 return phb_free(phb, FALSE);
     226                return phb_close(phb);
    244227        }
    245228        sock_make_blocking(source);
     
    248231                   phb->host, phb->port);
    249232        if (send(source, cmd, strlen(cmd), 0) < 0) {
    250                 return phb_free(phb, FALSE);
     233                return phb_close(phb);
    251234        }
    252235
     
    259242                g_free(t2);
    260243                if (send(source, cmd, strlen(cmd), 0) < 0) {
    261                         return phb_free(phb, FALSE);
     244                        return phb_close(phb);
    262245                }
    263246        }
     
    265248        g_snprintf(cmd, sizeof(cmd), "\r\n");
    266249        if (send(source, cmd, strlen(cmd), 0) < 0) {
    267                 return phb_free(phb, FALSE);
     250                return phb_close(phb);
    268251        }
    269252
     
    296279        if (read(source, packet, 9) >= 4 && packet[1] == 90) {
    297280                phb->func(phb->data, source, B_EV_IO_READ);
    298                 return phb_free(phb, TRUE);
    299         }
    300 
    301         return phb_free(phb, FALSE);
     281                g_free(phb->host);
     282                g_free(phb);
     283                return FALSE;
     284        }
     285
     286        return phb_close(phb);
    302287}
    303288
     
    309294        socklen_t len;
    310295        int error = ETIMEDOUT;
    311         gboolean is_socks4a = (proxytype == PROXY_SOCKS4A);
    312296
    313297        if (phb->inpa > 0) {
     
    316300        len = sizeof(error);
    317301        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    318                 return phb_free(phb, FALSE);
     302                return phb_close(phb);
    319303        }
    320304        sock_make_blocking(source);
    321305
    322         if (!is_socks4a && !(hp = gethostbyname(phb->host))) {
    323                 return phb_free(phb, FALSE);
     306        /* XXX does socks4 not support host name lookups by the proxy? */
     307        if (!(hp = gethostbyname(phb->host))) {
     308                return phb_close(phb);
    324309        }
    325310
     
    328313        packet[2] = phb->port >> 8;
    329314        packet[3] = phb->port & 0xff;
    330         if (is_socks4a) {
    331                 packet[4] = 0;
    332                 packet[5] = 0;
    333                 packet[6] = 0;
    334                 packet[7] = 1;
    335         } else {
    336                 packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
    337                 packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
    338                 packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
    339                 packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
    340         }
     315        packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
     316        packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
     317        packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
     318        packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
    341319        packet[8] = 0;
    342320        if (write(source, packet, 9) != 9) {
    343                 return phb_free(phb, FALSE);
    344         }
    345 
    346         if (is_socks4a) {
    347                 size_t host_len = strlen(phb->host) + 1; /* include the \0 */
    348 
    349                 if (write(source, phb->host, host_len) != host_len) {
    350                         return phb_free(phb, FALSE);
    351                 }
     321                return phb_close(phb);
    352322        }
    353323
     
    378348
    379349        if (read(source, buf, 10) < 10) {
    380                 return phb_free(phb, FALSE);
     350                return phb_close(phb);
    381351        }
    382352        if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
    383                 return phb_free(phb, FALSE);
     353                return phb_close(phb);
    384354        }
    385355
    386356        phb->func(phb->data, source, B_EV_IO_READ);
    387         return phb_free(phb, TRUE);
     357        g_free(phb->host);
     358        g_free(phb);
     359
     360        return FALSE;
    388361}
    389362
     
    404377
    405378        if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
    406                 phb_free(phb, FALSE);
     379                phb_close(phb);
    407380                return;
    408381        }
     
    419392
    420393        if (read(source, buf, 2) < 2) {
    421                 return phb_free(phb, FALSE);
     394                return phb_close(phb);
    422395        }
    423396
    424397        if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
    425                 return phb_free(phb, FALSE);
     398                return phb_close(phb);
    426399        }
    427400
     
    439412
    440413        if (read(source, buf, 2) < 2) {
    441                 return phb_free(phb, FALSE);
     414                return phb_close(phb);
    442415        }
    443416
    444417        if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
    445                 return phb_free(phb, FALSE);
     418                return phb_close(phb);
    446419        }
    447420
     
    454427                memcpy(buf + 2 + i + 1, proxypass, j);
    455428                if (write(source, buf, 3 + i + j) < 3 + i + j) {
    456                         return phb_free(phb, FALSE);
     429                        return phb_close(phb);
    457430                }
    458431
     
    478451        len = sizeof(error);
    479452        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    480                 return phb_free(phb, FALSE);
     453                return phb_close(phb);
    481454        }
    482455        sock_make_blocking(source);
     
    496469
    497470        if (write(source, buf, i) < i) {
    498                 return phb_free(phb, FALSE);
     471                return phb_close(phb);
    499472        }
    500473
     
    514487}
    515488
    516 static const proxy_connect_func proxy_connect_funcs_array[] = {
    517         proxy_connect_none,   /* PROXY_NONE */
    518         proxy_connect_http,   /* PROXY_HTTP */
    519         proxy_connect_socks4, /* PROXY_SOCKS4 */
    520         proxy_connect_socks5, /* PROXY_SOCKS5 */
    521         proxy_connect_socks4, /* PROXY_SOCKS4A */
    522 };
    523489
    524490/* Export functions */
     
    527493{
    528494        struct PHB *phb;
    529         proxy_connect_func fun;
    530         int fd;
    531 
    532         if (!phb_hash) {
    533                 phb_hash = g_hash_table_new(g_int_hash, g_int_equal);
    534         }
    535495
    536496        if (!host || port <= 0 || !func || strlen(host) > 128) {
     
    542502        phb->data = data;
    543503
    544         if (proxyhost[0] && proxyport > 0 && proxytype >= 0 && proxytype < G_N_ELEMENTS(proxy_connect_funcs_array)) {
    545                 fun = proxy_connect_funcs_array[proxytype];
    546         } else {
    547                 fun = proxy_connect_none;
    548         }
    549 
    550         fd = fun(host, port, phb);
    551 
    552         if (fd != -1) {
    553                 g_hash_table_insert(phb_hash, &phb->fd, phb);
    554         }
    555 
    556         return fd;
    557 }
    558 
    559 void proxy_disconnect(int fd)
    560 {
    561         struct PHB *phb = g_hash_table_lookup(phb_hash, &fd);
    562 
    563         if (!phb) {
    564                 /* not in the early part of the connection - just close the fd */
    565                 closesocket(fd);
    566                 return;
    567         }
    568 
    569         if (phb->inpa) {
    570                 b_event_remove(phb->inpa);
    571                 phb->inpa = 0;
    572         }
    573 
    574         /* avoid calling the callback, which might result in double-free */
    575         phb->func = NULL;
    576 
    577         /* close and free */
    578         phb_free(phb, FALSE);
    579 }
     504        if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) {
     505                return proxy_connect_none(host, port, phb);
     506        } else if (proxytype == PROXY_HTTP) {
     507                return proxy_connect_http(host, port, phb);
     508        } else if (proxytype == PROXY_SOCKS4) {
     509                return proxy_connect_socks4(host, port, phb);
     510        } else if (proxytype == PROXY_SOCKS5) {
     511                return proxy_connect_socks5(host, port, phb);
     512        }
     513
     514        g_free(phb);
     515        return -1;
     516}
  • lib/proxy.h

    r3fbce97 r63cad66  
    4040#define PROXY_SOCKS4 2
    4141#define PROXY_SOCKS5 3
    42 #define PROXY_SOCKS4A 4
    4342
    4443extern char proxyhost[128];
     
    4948
    5049G_MODULE_EXPORT int proxy_connect(const char *host, int port, b_event_handler func, gpointer data);
    51 G_MODULE_EXPORT void proxy_disconnect(int fd);
    5250
    5351#endif /* _PROXY_H_ */
  • lib/ssl_gnutls.c

    r3fbce97 r63cad66  
    455455        }
    456456
    457         proxy_disconnect(conn->fd);
     457        closesocket(conn->fd);
    458458
    459459        if (conn->session) {
  • lib/ssl_nss.c

    r3fbce97 r63cad66  
    226226        if (conn->prfd) {
    227227                PR_Close(conn->prfd);
    228         } else if (source >= 0) {
    229                 /* proxy_disconnect() would be redundant here */
     228        }
     229        if (source >= 0) {
    230230                closesocket(source);
    231231        }
     
    305305        if (conn->prfd) {
    306306                PR_Close(conn->prfd);
    307         } else if (conn->fd) {
    308                 proxy_disconnect(conn->fd);
    309307        }
    310308
  • lib/ssl_openssl.c

    r3fbce97 r63cad66  
    131131                conn->func(conn->data, 1, NULL, cond);
    132132                if (source >= 0) {
    133                         proxy_disconnect(source);
     133                        closesocket(source);
    134134                }
    135135                ssl_conn_free(conn);
     
    276276        }
    277277
    278         proxy_disconnect(conn->fd);
     278        closesocket(conn->fd);
    279279
    280280        ssl_conn_free(conn);
  • lib/url.c

    r3fbce97 r63cad66  
    4848                } else if (g_strncasecmp(set_url, "socks5", i - set_url) == 0) {
    4949                        url->proto = PROTO_SOCKS5;
    50                 } else if (g_strncasecmp(set_url, "socks4a", i - set_url) == 0) {
    51                         url->proto = PROTO_SOCKS4A;
    5250                } else {
    5351                        return 0;
  • lib/url.h

    r3fbce97 r63cad66  
    3030#define PROTO_SOCKS4    3
    3131#define PROTO_SOCKS5    4
    32 #define PROTO_SOCKS4A   5
    3332#define PROTO_DEFAULT   PROTO_HTTP
    3433
  • log.c

    r3fbce97 r63cad66  
    5151void log_link(int level, int output)
    5252{
    53         void (*output_function)(int level, const char *logmessage) = &log_null;
    54 
    55         if (output == LOGOUTPUT_NULL) {
    56                 output_function = &log_null;
    57         } else if (output == LOGOUTPUT_IRC) {
    58                 output_function = &log_irc;
    59         } else if (output == LOGOUTPUT_SYSLOG) {
    60                 output_function = &log_syslog;
    61         } else if (output == LOGOUTPUT_CONSOLE) {
    62                 output_function = &log_console;
    63         }
    64 
    65         if (level == LOGLVL_INFO) {
    66                 logoutput.informational = output_function;
     53        /* I know it's ugly, but it works and I didn't feel like messing with pointer to function pointers */
     54
     55        if (level == LOGLVL_INFO) {
     56                if (output == LOGOUTPUT_NULL) {
     57                        logoutput.informational = &log_null;
     58                } else if (output == LOGOUTPUT_IRC) {
     59                        logoutput.informational = &log_irc;
     60                } else if (output == LOGOUTPUT_SYSLOG) {
     61                        logoutput.informational = &log_syslog;
     62                } else if (output == LOGOUTPUT_CONSOLE) {
     63                        logoutput.informational = &log_console;
     64                }
    6765        } else if (level == LOGLVL_WARNING) {
    68                 logoutput.warning = output_function;
     66                if (output == LOGOUTPUT_NULL) {
     67                        logoutput.warning = &log_null;
     68                } else if (output == LOGOUTPUT_IRC) {
     69                        logoutput.warning = &log_irc;
     70                } else if (output == LOGOUTPUT_SYSLOG) {
     71                        logoutput.warning = &log_syslog;
     72                } else if (output == LOGOUTPUT_CONSOLE) {
     73                        logoutput.warning = &log_console;
     74                }
    6975        } else if (level == LOGLVL_ERROR) {
    70                 logoutput.error = output_function;
     76                if (output == LOGOUTPUT_NULL) {
     77                        logoutput.error = &log_null;
     78                } else if (output == LOGOUTPUT_IRC) {
     79                        logoutput.error = &log_irc;
     80                } else if (output == LOGOUTPUT_SYSLOG) {
     81                        logoutput.error = &log_syslog;
     82                } else if (output == LOGOUTPUT_CONSOLE) {
     83                        logoutput.error = &log_console;
     84                }
    7185        }
    7286#ifdef DEBUG
    7387        else if (level == LOGLVL_DEBUG) {
    74                 logoutput.debug = output_function;
     88                if (output == LOGOUTPUT_NULL) {
     89                        logoutput.debug = &log_null;
     90                } else if (output == LOGOUTPUT_IRC) {
     91                        logoutput.debug = &log_irc;
     92                } else if (output == LOGOUTPUT_SYSLOG) {
     93                        logoutput.debug = &log_syslog;
     94                } else if (output == LOGOUTPUT_CONSOLE) {
     95                        logoutput.debug = &log_console;
     96                }
    7597        }
    7698#endif
  • otr.c

    r3fbce97 r63cad66  
    187187/* update op/voice flag of given user according to encryption state and settings
    188188   returns 0 if neither op_buddies nor voice_buddies is set to "encrypted",
    189    i.e. msgstate should be announced separately */
     189   i.e. msgstate should be announced seperately */
    190190int otr_update_modeflags(irc_t *irc, irc_user_t *u);
    191191
     
    216216void otr_disconnect_all(irc_t *irc);
    217217
    218 /* modifies string in-place, replacing \x03 with '?',
    219    as a quick way to prevent remote users from messing with irc colors */
    220 static char *otr_filter_colors(char *msg);
    221 
    222218/* functions to be called for certain events */
    223219static const struct irc_plugin otr_plugin;
    224 
    225 #define OTR_COLOR_TRUSTED "03"     /* green */
    226 #define OTR_COLOR_UNTRUSTED "05"   /* red */
    227220
    228221/*** routines declared in otr.h: ***/
     
    441434
    442435        /* don't do OTR on certain (not classic IM) protocols, e.g. twitter */
    443         if (ic->acc->prpl->options & OPT_NOOTR ||
    444             iu->bu->flags & BEE_USER_NOOTR) {
     436        if (ic->acc->prpl->options & OPT_NOOTR) {
    445437                return msg;
    446438        }
     
    459451        } else if (!newmsg) {
    460452                /* this was a non-OTR message */
    461                 return otr_filter_colors(msg);
     453                return msg;
    462454        } else {
    463455                /* we're done with the original msg, which will be caller-freed. */
     
    480472
    481473        /* don't do OTR on certain (not classic IM) protocols, e.g. twitter */
    482         if (ic->acc->prpl->options & OPT_NOOTR ||
    483             iu->bu->flags & BEE_USER_NOOTR) {
     474        if (ic->acc->prpl->options & OPT_NOOTR) {
    484475                return msg;
    485476        }
     
    751742}
    752743
    753 static char *otr_filter_colors(char *msg)
    754 {
    755         return str_reject_chars(msg, "\x02\x03", '?');
    756 }
    757 
    758 /* returns newly allocated string */
    759 static char *otr_color_encrypted(char *msg, char *color, gboolean is_query) {
    760         char **lines;
    761         GString *out;
    762         int i;
    763 
    764         lines = g_strsplit(msg, "\n", -1);
    765 
    766         /* up to 4 extra chars per line (e.g., '\x03' + ("03"|"05") + ' ') */
    767         out = g_string_sized_new(strlen(msg) + g_strv_length(lines) * 4);
    768        
    769         for (i = 0; lines[i]; i++) {
    770                 char *line = lines[i];
    771 
    772                 if (i != 0) {
    773                         g_string_append_c(out, '\n');
    774 
    775                 } else if (is_query && g_strncasecmp(line, "/me ", 4) == 0) {
    776                         /* in a query window, keep "/me " uncolored at the beginning */
    777                         line += 4;
    778                         g_string_append(out, "/me ");
    779                 }
    780 
    781                 g_string_append_c(out, '\x03');
    782                 g_string_append(out, color);
    783 
    784                 /* comma in first place could mess with the color code */
    785                 if (line[0] == ',') {
    786                         /* insert a space between color spec and message */
    787                         g_string_append_c(out, ' ');
    788                 }
    789 
    790                 g_string_append(out, otr_filter_colors(line));
    791         }
    792 
    793         g_strfreev(lines);
    794 
    795         return g_string_free(out, FALSE);
    796 }
    797 
    798744void op_convert_msg(void *opdata, ConnContext *ctx, OtrlConvertType typ,
    799745                    char **dst, const char *src)
     
    806752        if (typ == OTRL_CONVERT_RECEIVING) {
    807753                char *msg = g_strdup(src);
     754                char *buf = msg;
    808755
    809756                /* HTML decoding */
     
    812759                    set_getbool(&ic->bee->set, "strip_html")) {
    813760                        strip_html(msg);
    814 
    815                         /* msg is borrowed by *dst (unless the next if decides to color it) */
    816761                        *dst = msg;
    817762                }
     
    819764                /* coloring */
    820765                if (set_getbool(&ic->bee->set, "otr_color_encrypted")) {
     766                        int color;                /* color according to f'print trust */
     767                        char *pre = "", *sep = "";    /* optional parts */
    821768                        const char *trust = ctx->active_fingerprint->trust;
    822                         char *color = (trust && *trust) ? OTR_COLOR_TRUSTED : OTR_COLOR_UNTRUSTED;
    823                         gboolean is_query = (irc_user_msgdest(iu) == irc->user->nick);
    824 
    825                         /* the return value of otr_color_encrypted() is borrowed by *dst */
    826                         *dst = otr_color_encrypted(msg, color, is_query);
    827 
    828                         /* this branch doesn't need msg */
    829                         g_free(msg);
     769
     770                        if (trust && trust[0] != '\0') {
     771                                color = 3;   /* green */
     772                        } else {
     773                                color = 5;   /* red */
     774
     775                        }
     776                        /* in a query window, keep "/me " uncolored at the beginning */
     777                        if (g_strncasecmp(msg, "/me ", 4) == 0
     778                            && irc_user_msgdest(iu) == irc->user->nick) {
     779                                msg += 4;  /* skip */
     780                                pre = "/me ";
     781                        }
     782
     783                        /* comma in first place could mess with the color code */
     784                        if (msg[0] == ',') {
     785                                /* insert a space between color spec and message */
     786                                sep = " ";
     787                        }
     788
     789                        *dst = g_strdup_printf("%s\x03%.2d%s%s\x0F", pre,
     790                                               color, sep, msg);
     791                        g_free(buf);
    830792                }
    831793        } else {
     
    13951357
    13961358        if (u) {
    1397                 /* just show this as a regular message */
    1398                 irc_usermsg(u, "<<\002OTR\002>> %s", msg);
     1359                /* display as a notice from this particular user */
     1360                irc_usernotice(u, "%s", msg);
    13991361        } else {
    14001362                irc_rootmsg(irc, "[otr] %s", msg);
     
    17331695        *p = '\0';
    17341696
    1735         /* remove trailing whitespace */
    1736         g_strchomp(prefix);
    1737 
    17381697        /* find first key which matches the given prefix */
    17391698        n = strlen(prefix);
  • protocols/account.c

    r3fbce97 r63cad66  
    8484                    strstr(a->user, "@googlemail.com")) {
    8585                        strcpy(tag, "gtalk");
     86                } else if (strstr(a->user, "@chat.facebook.com")) {
     87                        strcpy(tag, "fb");
    8688                }
    8789        }
  • protocols/bee.h

    r3fbce97 r63cad66  
    6262        BEE_USER_LOCAL = 256,   /* Locally-added contacts (not in real contact list) */
    6363        BEE_USER_SPECIAL = 512, /* Denotes a user as being special */
    64         BEE_USER_NOOTR = 4096,  /* Per-user version of OPT_NOOTR */
    6564} bee_user_flags_t;
    6665
     
    105104        gboolean (*user_status)(bee_t *bee, struct bee_user *bu, struct bee_user *old);
    106105        /* On every incoming message. sent_at = 0 means unknown. */
    107         gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at);
     106        gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at);
    108107        /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */
    109108        gboolean (*user_typing)(bee_t *bee, bee_user_t *bu, guint32 flags);
     
    118117        /* System messages of any kind. */
    119118        gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text);
    120         gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at);
     119        gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at);
    121120        gboolean (*chat_add_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu);
    122         gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *reason);
     121        gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu);
    123122        gboolean (*chat_topic)(bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu);
    124123        gboolean (*chat_name_hint)(bee_t *bee, struct groupchat *c, const char *name);
     
    129128        void (*ft_close)(struct im_connection *ic, struct file_transfer *ft);
    130129        void (*ft_finished)(struct im_connection *ic, struct file_transfer *ft);
    131 
    132         void (*log)(bee_t *bee, const char *tag, const char *msg);
    133130} bee_ui_funcs_t;
    134131
  • protocols/bee_chat.c

    r3fbce97 r63cad66  
    9595}
    9696
    97 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at)
     97void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at)
    9898{
    9999        struct im_connection *ic = c->ic;
    100100        bee_t *bee = ic->bee;
    101101        bee_user_t *bu;
    102         gboolean temp = FALSE;
     102        gboolean temp;
    103103        char *s;
    104104
    105         if (handle_is_self(ic, who) && !(flags & OPT_SELFMESSAGE)) {
     105        /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
     106        if (handle_is_self(ic, who)) {
    106107                return;
    107108        }
     
    121122
    122123        if (bee->ui->chat_msg) {
    123                 bee->ui->chat_msg(bee, c, bu, msg, flags, sent_at);
     124                bee->ui->chat_msg(bee, c, bu, msg, sent_at);
    124125        }
    125126
     
    229230
    230231        if (bee->ui->chat_remove_user && bu) {
    231                 bee->ui->chat_remove_user(bee, c, bu, reason);
     232                bee->ui->chat_remove_user(bee, c, bu);
    232233        }
    233234}
  • protocols/bee_user.c

    r3fbce97 r63cad66  
    247247}
    248248
    249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32 flags, time_t sent_at)
     249void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, uint32_t flags, time_t sent_at)
    250250{
    251251        bee_t *bee = ic->bee;
     
    265265
    266266        if (bee->ui->user_msg && bu) {
    267                 bee->ui->user_msg(bee, bu, msg, flags, sent_at);
     267                bee->ui->user_msg(bee, bu, msg, sent_at);
    268268        } else {
    269269                imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg);
     
    297297}
    298298
    299 void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags)
     299void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags)
    300300{
    301301        bee_user_t *bu;
  • protocols/ft.h

    r3fbce97 r63cad66  
    5858 *                                    | accept
    5959 *                                    V
    60  *                     /------ /-------------\                    /--------------------------\
    61  *         out_of_data |       | TRANSFERRING | -----------------> | TRANSFERRING | CANCELED |
    62  *                     \-----> \-------------/  [canceled,]free   \--------------------------/
     60 *                     /------ /-------------\                    /------------------------\
     61 *         out_of_data |       | TRANSFERING | -----------------> | TRANSFERING | CANCELED |
     62 *                     \-----> \-------------/  [canceled,]free   \------------------------/
    6363 *                                    |
    6464 *                                    | finished,free
    6565 *                                    V
    66  *                       /-------------------------\
    67  *                       | TRANSFERRING | FINISHED |
    68  *                       \-------------------------/
     66 *                       /------------------------\
     67 *                       | TRANSFERING | FINISHED |
     68 *                       \------------------------/
    6969 */
    7070typedef struct file_transfer {
     
    115115
    116116        /*
    117          * If set, called after successful connection setup.
     117         * If set, called after succesful connection setup.
    118118         */
    119119        void (*accept)(struct file_transfer *file);
  • protocols/jabber/conference.c

    r3fbce97 r63cad66  
    2626
    2727static xt_status jabber_chat_join_failed(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    28 static xt_status jabber_chat_self_message(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    2928
    3029struct groupchat *jabber_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password)
     
    122121        }
    123122        if (bud) {
    124                 struct groupchat *c = jabber_chat_by_jid(ic, bud->bare_jid);
    125                 if (c) {
    126                         jabber_chat_free(c);
    127                 }
     123                jabber_chat_free(jabber_chat_by_jid(ic, bud->bare_jid));
    128124        }
    129125
    130126        return XT_HANDLED;
    131 }
    132 
    133 static xt_status jabber_chat_self_message(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    134 {
    135         /* This is a self message sent by this bitlbee - just drop it */
    136         return XT_ABORT;
    137127}
    138128
     
    181171        node = jabber_make_packet("message", "groupchat", jc->name, node);
    182172
    183         jabber_cache_add(ic, node, jabber_chat_self_message);
    184 
    185         return !jabber_write_packet(ic, node);
     173        if (!jabber_write_packet(ic, node)) {
     174                xt_free_node(node);
     175                return 0;
     176        }
     177        xt_free_node(node);
     178
     179        return 1;
    186180}
    187181
     
    305299                                        }
    306300                                }
     301
     302                                /* Some program-specific restrictions. */
     303                                imcb_clean_handle(ic, bud->ext_jid);
    307304                        }
    308305                        bud->flags |= JBFLAG_IS_ANONYMOUS;
     
    334331        } else if (type) { /* type can only be NULL or "unavailable" in this function */
    335332                if ((bud->flags & JBFLAG_IS_CHATROOM) && bud->ext_jid) {
    336                         char *reason = NULL;
    337                         char *status = NULL;
    338                         char *status_text = NULL;
    339                        
    340                         if ((c = xt_find_node_by_attr(node->children, "x", "xmlns", XMLNS_MUC_USER))) {
    341                                 struct xt_node *c2 = c->children;
    342 
    343                                 while ((c2 = xt_find_node(c2, "status"))) {
    344                                         char *code = xt_find_attr(c2, "code");
    345                                         if (g_strcmp0(code, "301") == 0) {
    346                                                 status = "Banned";
    347                                                 break;
    348                                         } else if (g_strcmp0(code, "303") == 0) {
    349                                                 /* This could be handled in a cleverer way,
    350                                                  * but let's just show a literal part/join for now */
    351                                                 status = "Changing nicks";
    352                                                 break;
    353                                         } else if (g_strcmp0(code, "307") == 0) {
    354                                                 status = "Kicked";
    355                                                 break;
    356                                         }
    357                                         c2 = c2->next;
    358                                 }
    359 
    360                                 /* Sometimes the status message is in presence/x/item/reason */
    361                                 if ((c2 = xt_find_path(c, "item/reason")) && c2->text && c2->text_len) {
    362                                         status_text = c2->text;
    363                                 }
    364                         }
    365 
    366                         /* Sometimes the status message is right inside <presence> */
    367                         if ((c = xt_find_node(node->children, "status")) && c->text && c->text_len) {
    368                                 status_text = c->text;
    369                         }
    370 
    371                         if (status_text && status) {
    372                                 reason = g_strdup_printf("%s: %s", status, status_text);
    373                         } else {
    374                                 reason = g_strdup(status_text ? : status);
    375                         }
    376 
    377333                        s = strchr(bud->ext_jid, '/');
    378334                        if (s) {
    379335                                *s = 0;
    380336                        }
    381                         imcb_chat_remove_buddy(chat, bud->ext_jid, reason);
     337                        imcb_chat_remove_buddy(chat, bud->ext_jid, NULL);
    382338                        if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) {
    383                                 imcb_remove_buddy(ic, bud->ext_jid, reason);
     339                                imcb_remove_buddy(ic, bud->ext_jid, NULL);
    384340                        }
    385341                        if (s) {
    386342                                *s = '/';
    387343                        }
    388 
    389                         g_free(reason);
    390344                }
    391345
     
    406360        char *final_from = NULL;
    407361        char *bare_jid = NULL;
    408         guint32 flags = 0;
    409362
    410363        from = (bud) ? bud->full_jid : xt_find_attr(node, "from");
     
    443396
    444397        if (subject && chat) {
    445                 char *subject_text = subject->text_len > 0 ? subject->text : "";
     398                char *subject_text = subject->text_len > 0 ? subject->text : NULL;
    446399                if (g_strcmp0(chat->topic, subject_text) != 0) {
    447400                        bare_jid = (bud) ? jabber_get_bare_jid(bud->ext_jid) : NULL;
     
    449402                                        jabber_get_timestamp(node));
    450403                        g_free(bare_jid);
    451                         bare_jid = NULL;
    452404                }
    453405        }
     
    470422                imcb_chat_log(chat, "From conference server: %s", body->text);
    471423                return;
    472         } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me &&
    473                    (jabber_cache_handle_packet(ic, node) == XT_ABORT)) {
    474                 /* Self message marked by this bitlbee, don't show it */
     424        } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me) {
     425                /* exclude self-messages since they would get filtered out
     426                 * but not the ones in the backlog */
    475427                return;
    476428        }
    477429
    478         if (bud) {
     430        if (bud && jc && bud != jc->me) {
    479431                bare_jid = jabber_get_bare_jid(bud->ext_jid ? bud->ext_jid : bud->full_jid);
    480432                final_from = bare_jid;
    481                 flags = (bud == jc->me) ? OPT_SELFMESSAGE : 0;
    482433        } else {
    483434                final_from = nick;
    484435        }
    485436
    486         imcb_chat_msg(chat, final_from, body->text, flags, jabber_get_timestamp(node));
     437        imcb_chat_msg(chat, final_from, body->text, 0, jabber_get_timestamp(node));
    487438
    488439        g_free(bare_jid);
  • protocols/jabber/hipchat.c

    r3fbce97 r63cad66  
    4242                *sep = '/';
    4343        }
    44 
    45         jd->muc_host = g_strdup(xt_find_attr(node, "muc_host"));
    4644
    4745        /* Hipchat's auth doesn't expect a restart here */
     
    9492
    9593}
    96 
    97 /* Returns a newly allocated string that tries to match the "slug" part of the JID using an
    98  * approximation of the method used by the server. This might fail in some rare conditions
    99  * (old JIDs generated a different way, locale settings unicode, etc) */
    100 char *hipchat_make_channel_slug(const char *name)
    101 {
    102         char *lower;
    103         char *new = g_malloc(strlen(name) + 1);
    104         int i = 0;
    105 
    106         do {
    107                 if (*name == ' ') {
    108                         new[i++] = '_';
    109                 } else if (*name && !strchr("\"&'/:<>@", *name)) {
    110                         new[i++] = *name;
    111                 }
    112         } while (*(name++));
    113 
    114         new[i] = '\0';
    115 
    116         lower = g_utf8_strdown(new, -1);
    117         g_free(new);
    118 
    119         return lower;
    120 }
    121 
    122 char *hipchat_guess_channel_name(struct im_connection *ic, const char *name)
    123 {
    124         struct jabber_data *jd = ic->proto_data;
    125         char *slug, *retval, *underscore;
    126        
    127         if (!(underscore = strchr(jd->username, '_')) || !jd->muc_host) {
    128                 return NULL;
    129         }
    130 
    131         slug = hipchat_make_channel_slug(name);
    132 
    133         /* Get the organization ID from the username, before the underscore */
    134         *underscore = '\0';
    135 
    136         retval = g_strdup_printf("%s_%s@%s", jd->username, slug, jd->muc_host);
    137 
    138         *underscore = '_';
    139 
    140         g_free(slug);
    141 
    142         return retval;
    143 }
  • protocols/jabber/io.c

    r3fbce97 r63cad66  
    147147}
    148148
    149 static gboolean jabber_feed_input(struct im_connection *ic, char *buf, int size)
    150 {
    151         struct jabber_data *jd = ic->proto_data;
    152 
    153         /* Allow not passing a size for debugging purposes.
    154          * This never happens when reading from the socket */
    155         if (size == -1) {
    156                 size = strlen(buf);
    157         }
    158 
    159         /* Parse. */
    160         if (xt_feed(jd->xt, buf, size) < 0) {
    161                 imcb_error(ic, "XML stream error");
    162                 imc_logout(ic, TRUE);
    163                 return FALSE;
    164         }
    165 
    166         /* Execute all handlers. */
    167         if (!xt_handle(jd->xt, NULL, 1)) {
    168                 /* Don't do anything, the handlers should have
    169                    aborted the connection already. */
    170                 return FALSE;
    171         }
    172 
    173         if (jd->flags & JFLAG_STREAM_RESTART) {
    174                 jd->flags &= ~JFLAG_STREAM_RESTART;
    175                 jabber_start_stream(ic);
    176         }
    177 
    178         /* Garbage collection. */
    179         xt_cleanup(jd->xt, NULL, 1);
    180 
    181         /* This is a bit hackish, unfortunately. Although xmltree
    182            has nifty event handler stuff, it only calls handlers
    183            when nodes are complete. Since the server should only
    184            send an opening <stream:stream> tag, we have to check
    185            this by hand. :-( */
    186         if (!(jd->flags & JFLAG_STREAM_STARTED) && jd->xt && jd->xt->root) {
    187                 if (g_strcasecmp(jd->xt->root->name, "stream:stream") == 0) {
    188                         jd->flags |= JFLAG_STREAM_STARTED;
    189 
    190                         /* If there's no version attribute, assume
    191                            this is an old server that can't do SASL
    192                            authentication. */
    193                         if (!set_getbool(&ic->acc->set, "sasl") || !sasl_supported(ic)) {
    194                                 /* If there's no version= tag, we suppose
    195                                    this server does NOT implement: XMPP 1.0,
    196                                    SASL and TLS. */
    197                                 if (set_getbool(&ic->acc->set, "tls")) {
    198                                         imcb_error(ic, "TLS is turned on for this "
    199                                                    "account, but is not supported by this server");
    200                                         imc_logout(ic, FALSE);
    201                                         return FALSE;
    202                                 } else {
    203                                         if (!jabber_init_iq_auth(ic)) {
    204                                                 return FALSE;
    205                                         }
    206                                 }
    207                         }
    208                 } else {
     149static gboolean jabber_read_callback(gpointer data, gint fd, b_input_condition cond)
     150{
     151        struct im_connection *ic = data;
     152        struct jabber_data *jd = ic->proto_data;
     153        char buf[512];
     154        int st;
     155
     156        if (jd->fd == -1) {
     157                return FALSE;
     158        }
     159
     160        if (jd->ssl) {
     161                st = ssl_read(jd->ssl, buf, sizeof(buf));
     162        } else {
     163                st = read(jd->fd, buf, sizeof(buf));
     164        }
     165
     166        if (st > 0) {
     167                /* Parse. */
     168                if (xt_feed(jd->xt, buf, st) < 0) {
    209169                        imcb_error(ic, "XML stream error");
    210170                        imc_logout(ic, TRUE);
    211171                        return FALSE;
    212172                }
    213         }
    214 
    215         return TRUE;
    216 }
    217 
    218 
    219 static gboolean jabber_read_callback(gpointer data, gint fd, b_input_condition cond)
    220 {
    221         struct im_connection *ic = data;
    222         struct jabber_data *jd = ic->proto_data;
    223         char buf[512];
    224         int st;
    225 
    226         if (jd->fd == -1) {
    227                 return FALSE;
    228         }
    229 
    230         if (jd->ssl) {
    231                 st = ssl_read(jd->ssl, buf, sizeof(buf));
    232         } else {
    233                 st = read(jd->fd, buf, sizeof(buf));
    234         }
    235 
    236         if (st > 0) {
    237                 if (!jabber_feed_input(ic, buf, st)) {
     173
     174                /* Execute all handlers. */
     175                if (!xt_handle(jd->xt, NULL, 1)) {
     176                        /* Don't do anything, the handlers should have
     177                           aborted the connection already. */
    238178                        return FALSE;
     179                }
     180
     181                if (jd->flags & JFLAG_STREAM_RESTART) {
     182                        jd->flags &= ~JFLAG_STREAM_RESTART;
     183                        jabber_start_stream(ic);
     184                }
     185
     186                /* Garbage collection. */
     187                xt_cleanup(jd->xt, NULL, 1);
     188
     189                /* This is a bit hackish, unfortunately. Although xmltree
     190                   has nifty event handler stuff, it only calls handlers
     191                   when nodes are complete. Since the server should only
     192                   send an opening <stream:stream> tag, we have to check
     193                   this by hand. :-( */
     194                if (!(jd->flags & JFLAG_STREAM_STARTED) && jd->xt && jd->xt->root) {
     195                        if (g_strcasecmp(jd->xt->root->name, "stream:stream") == 0) {
     196                                jd->flags |= JFLAG_STREAM_STARTED;
     197
     198                                /* If there's no version attribute, assume
     199                                   this is an old server that can't do SASL
     200                                   authentication. */
     201                                if (!set_getbool(&ic->acc->set, "sasl") || !sasl_supported(ic)) {
     202                                        /* If there's no version= tag, we suppose
     203                                           this server does NOT implement: XMPP 1.0,
     204                                           SASL and TLS. */
     205                                        if (set_getbool(&ic->acc->set, "tls")) {
     206                                                imcb_error(ic, "TLS is turned on for this "
     207                                                           "account, but is not supported by this server");
     208                                                imc_logout(ic, FALSE);
     209                                                return FALSE;
     210                                        } else {
     211                                                return jabber_init_iq_auth(ic);
     212                                        }
     213                                }
     214                        } else {
     215                                imcb_error(ic, "XML stream error");
     216                                imc_logout(ic, TRUE);
     217                                return FALSE;
     218                        }
    239219                }
    240220        } else if (st == 0 || (st < 0 && !ssl_sockerr_again(jd->ssl))) {
  • protocols/jabber/iq.c

    r3fbce97 r63cad66  
    2828static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    2929static xt_status jabber_gmail_handle_new(struct im_connection *ic, struct xt_node *node);
    30 static xt_status jabber_iq_carbons_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    3130
    3231xt_status jabber_pkt_iq(struct xt_node *node, gpointer data)
     
    5352                      (c = xt_find_node(node->children, "time"))) ||
    5453                    !(s = xt_find_attr(c, "xmlns"))) {
    55 
    56                         reply = jabber_make_error_packet(node, "service-unavailable", "cancel", NULL);
    57                         st = jabber_write_packet(ic, reply);
    58                         xt_free_node(reply);
    59                         return st;
     54                        /* Sigh. Who decided to suddenly invent new elements
     55                           instead of just sticking with <query/>? */
     56                        return XT_HANDLED;
    6057                }
    6158
     
    121118                                                   XMLNS_BYTESTREAMS,
    122119                                                   XMLNS_FILETRANSFER,
    123                                                    XMLNS_CARBONS,
    124120                                                   NULL };
    125121                        const char **f;
     
    138134                } else {
    139135                        xt_free_node(reply);
    140                         reply = jabber_make_error_packet(node, "service-unavailable", "cancel", NULL);
     136                        reply = jabber_make_error_packet(node, "feature-not-implemented", "cancel", NULL);
    141137                        pack = 0;
    142138                }
     
    389385        struct xt_node *response;
    390386        struct jabber_data *jd = ic->proto_data;
    391        
    392         response = jabber_make_packet("iq", "result", jd->me, NULL);
     387
     388        response = jabber_make_packet("iq", "result", g_strdup_printf("%s@%s", jd->username, jd->server), NULL);
    393389
    394390        jabber_cache_add(ic, response, NULL);
     
    10081004{
    10091005        struct jabber_data *jd = ic->proto_data;
    1010         struct xt_node *query, *id;
    1011 
    1012         if (!(query = xt_find_node(node->children, "query"))) {
    1013                 return XT_HANDLED;
    1014         }
    1015 
    1016         if (xt_find_node_by_attr(query->children, "feature", "var", XMLNS_CARBONS) &&
    1017             set_getbool(&ic->acc->set, "carbons")) {
    1018 
    1019                 struct xt_node *enable, *iq;
    1020 
    1021                 enable = xt_new_node("enable", NULL, NULL);
    1022                 xt_add_attr(enable, "xmlns", XMLNS_CARBONS);
    1023                 iq = jabber_make_packet("iq", "set", NULL, enable);
    1024 
    1025                 jabber_cache_add(ic, iq, jabber_iq_carbons_response);
    1026                 jabber_write_packet(ic, iq);
    1027         }
    1028 
    1029         if ((id = xt_find_node(query->children, "identity"))) {
     1006        struct xt_node *id;
     1007
     1008        if ((id = xt_find_path(node, "query/identity"))) {
    10301009                char *cat, *type, *name;
    10311010
     
    10441023        return XT_HANDLED;
    10451024}
    1046 
    1047 static xt_status jabber_iq_carbons_response(struct im_connection *ic,
    1048                                             struct xt_node *node, struct xt_node *orig)
    1049 {
    1050         struct jabber_error *err;
    1051 
    1052         if ((err = jabber_error_parse(xt_find_node(node->children, "error"), XMLNS_STANZA_ERROR))) {
    1053                 imcb_error(ic, "Error enabling carbons: %s%s%s",
    1054                            err->code, err->text ? ": " : "", err->text ? err->text : "");
    1055                 jabber_error_free(err);
    1056         } else {
    1057                 imcb_log(ic, "Carbons enabled");
    1058         }
    1059 
    1060         return XT_HANDLED;
    1061 }
  • protocols/jabber/jabber.c

    r3fbce97 r63cad66  
    114114        s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    115115
    116         s = set_add(&acc->set, "carbons", "true", set_eval_bool, acc);
    117         s->flags |= ACC_SET_OFFLINE_ONLY;
    118 
    119116        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
    120117                      ACC_FLAG_HANDLE_DOMAINS;
     
    151148        }
    152149
    153         if (strstr(jd->server, ".facebook.com")) {
    154                 imcb_error(ic, "Facebook's XMPP service is gone. Try this instead: https://wiki.bitlbee.org/HowtoFacebookMQTT");
    155                 imc_logout(ic, FALSE);
    156                 return;
    157         }
    158 
    159150        if ((s = strchr(jd->server, '/'))) {
    160151                *s = 0;
     
    176167                jd->fd = jd->r_inpa = jd->w_inpa = -1;
    177168
    178                 /* There are no other options atm, so assume google for everything
    179                    Facebook and MSN XMPP used to be here. RIP. */
    180                 jd->oauth2_service = &oauth2_service_google;
     169                if (strstr(jd->server, ".facebook.com")) {
     170                        jd->oauth2_service = &oauth2_service_facebook;
     171                } else {
     172                        jd->oauth2_service = &oauth2_service_google;
     173                }
    181174
    182175                oauth_params_parse(&p_in, ic->acc->pass);
     
    204197        } else {
    205198                jabber_connect(ic);
    206         }
    207 }
    208 
    209 static void jabber_xmlconsole_enable(struct im_connection *ic)
    210 {
    211         struct jabber_data *jd = ic->proto_data;
    212         const char *handle = JABBER_XMLCONSOLE_HANDLE;
    213         bee_user_t *bu;
    214        
    215         jd->flags |= JFLAG_XMLCONSOLE;
    216 
    217         if (!(bu = bee_user_by_handle(ic->bee, ic, handle))) {
    218                 bu = bee_user_new(ic->bee, ic, handle, 0);
    219                 bu->flags |= BEE_USER_NOOTR;
    220199        }
    221200}
     
    287266
    288267        if (set_getbool(&acc->set, "xmlconsole")) {
    289                 jabber_xmlconsole_enable(ic);
     268                jd->flags |= JFLAG_XMLCONSOLE;
     269                /* Shouldn't really do this at this stage already, maybe. But
     270                   I think this shouldn't break anything. */
     271                imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL);
    290272        }
    291273
     
    352334        }
    353335        if (jd->fd >= 0) {
    354                 proxy_disconnect(jd->fd);
     336                closesocket(jd->fd);
    355337        }
    356338
     
    363345        }
    364346
    365         if (jd->buddies) {
    366                 jabber_buddy_remove_all(ic);
    367         }
     347        jabber_buddy_remove_all(ic);
    368348
    369349        xt_free(jd->xt);
     
    375355        g_free(jd->internal_jid);
    376356        g_free(jd->gmail_tid);
    377         g_free(jd->muc_host);
    378357        g_free(jd->username);
    379358        g_free(jd->me);
     
    434413        }
    435414
    436         /* XEP-0364 suggests we add message processing hints (XEP-0334) to OTR messages,
    437            mostly to avoid carbons (XEP-0280) and server-side message archiving.
    438            OTR messages are roughly like this: /^\?OTR(.*\?| Error:|:)/
    439            But I'm going to simplify it to messages starting with "?OTR". */
    440         if (g_str_has_prefix(message, "?OTR")) {
    441                 int i;
    442                 char *hints[] = {
    443                         "no-copy", XMLNS_HINTS,
    444                         "no-permanent-store", XMLNS_HINTS,
    445                         "private", XMLNS_CARBONS,
    446                         NULL
    447                 };
    448                        
    449                 for (i = 0; hints[i]; i += 2) {
    450                         struct xt_node *hint;
    451                         hint = xt_new_node(hints[i], NULL, NULL);
    452                         xt_add_attr(hint, "xmlns", hints[i + 1]);
    453                         xt_add_child(node, hint);
    454                 }
    455         }
    456 
    457415        st = jabber_write_packet(ic, node);
    458416        xt_free_node(node);
     
    514472static void jabber_add_buddy(struct im_connection *ic, char *who, char *group)
    515473{
     474        struct jabber_data *jd = ic->proto_data;
     475
    516476        if (g_strcasecmp(who, JABBER_XMLCONSOLE_HANDLE) == 0) {
    517                 jabber_xmlconsole_enable(ic);
     477                jd->flags |= JFLAG_XMLCONSOLE;
     478                imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL);
    518479                return;
    519480        }
     
    559520        }
    560521
    561         if (jd->flags & JFLAG_HIPCHAT && jd->muc_host && !g_str_has_suffix(room, jd->muc_host)) {
    562                 char *guessed_name = hipchat_guess_channel_name(ic, room);
    563                 if (guessed_name) {
    564                         set_setstr(sets, "room", guessed_name);
    565                         g_free(guessed_name);
    566 
    567                         /* call this same function again with the fixed name */
    568                         return jabber_chat_join_(ic, set_getstr(sets, "room"), nick, password, sets);
    569                 }
    570         }
    571 
    572522        if (strchr(room, '@') == NULL) {
    573523                imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?",
     
    576526                imcb_error(ic, "Already present in chat `%s'", room);
    577527        } else {
    578                 /* jabber_chat_join without the underscore is the conference.c one */
    579528                return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password"));
    580529        }
     
    641590{
    642591        struct jabber_data *jd = ic->proto_data;
    643         struct jabber_buddy *bud, *bare;
     592        struct jabber_buddy *bud;
    644593
    645594        /* Enable typing notification related code from now. */
    646595        jd->flags |= JFLAG_WANT_TYPING;
    647596
    648         if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL ||
    649             (bare = jabber_buddy_by_jid(ic, who, GET_BUDDY_BARE)) == NULL) {
     597        if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL) {
    650598                /* Sending typing notifications to unknown buddies is
    651599                   unsupported for now. Shouldn't be a problem, I think. */
     
    653601        }
    654602
    655 
    656         if (bud->flags & JBFLAG_DOES_XEP85 || bare->flags & JBFLAG_DOES_XEP85) {
     603        if (bud->flags & JBFLAG_DOES_XEP85) {
    657604                /* We're only allowed to send this stuff if we know the other
    658                    side supports it. If the bare JID has the flag, all other
    659                    resources get it, too (That is the case in gtalk) */
     605                   side supports it. */
    660606
    661607                struct xt_node *node;
  • protocols/jabber/jabber.h

    r3fbce97 r63cad66  
    5050        JFLAG_GTALK =  0x100000,        /* Is Google Talk, as confirmed by iq discovery */
    5151        JFLAG_HIPCHAT = 0x200000,       /* Is hipchat, because prpl->name says so */
     52
     53        JFLAG_SASL_FB = 0x10000,        /* Trying Facebook authentication. */
    5254} jabber_flags_t;
    5355
     
    111113        GSList *streamhosts;
    112114        int have_streamhosts;
    113 
    114         char *muc_host;
    115115};
    116116
     
    228228#define XMLNS_XDATA        "jabber:x:data"                                       /* XEP-0004 */
    229229#define XMLNS_GMAILNOTIFY  "google:mail:notify"                                  /* Not a XEP */
    230 #define XMLNS_CARBONS      "urn:xmpp:carbons:2"                                  /* XEP-0280 */
    231 #define XMLNS_FORWARDING   "urn:xmpp:forward:0"                                  /* XEP-0297 */
    232 #define XMLNS_HINTS        "urn:xmpp:hints"                                      /* XEP-0334 */
    233230#define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"               /* XEP-0085 */
    234231#define XMLNS_DISCO_INFO   "http://jabber.org/protocol/disco#info"               /* XEP-0030 */
     
    341338
    342339extern const struct oauth2_service oauth2_service_google;
     340extern const struct oauth2_service oauth2_service_facebook;
    343341
    344342/* conference.c */
     
    358356xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    359357xt_status hipchat_handle_success(struct im_connection *ic, struct xt_node *node);
    360 char *hipchat_make_channel_slug(const char *name);
    361 char *hipchat_guess_channel_name(struct im_connection *ic, const char *name);
    362358
    363359#endif
  • protocols/jabber/jabber_util.c

    r3fbce97 r63cad66  
    514514                } else if (bud->resource && (flags & GET_BUDDY_EXACT)) {
    515515                        /* We want an exact match, so in thise case there shouldn't be a /resource. */
    516                         if (head != bud && head->resource == NULL) {
    517                                 return head;
    518                         } else {
    519                                 return NULL;
    520                         }
     516                        return NULL;
    521517                } else if (bud->resource == NULL || bud->next == NULL) {
    522518                        /* No need for selection if there's only one option. */
  • protocols/jabber/message.c

    r3fbce97 r63cad66  
    2424#include "jabber.h"
    2525
    26 static xt_status jabber_pkt_message_normal(struct xt_node *node, gpointer data, gboolean carbons_sent)
     26xt_status jabber_pkt_message(struct xt_node *node, gpointer data)
    2727{
    2828        struct im_connection *ic = data;
    29         struct jabber_data *jd = ic->proto_data;
    30         char *from = xt_find_attr(node, carbons_sent ? "to" : "from");
     29        char *from = xt_find_attr(node, "from");
    3130        char *type = xt_find_attr(node, "type");
    3231        char *id = xt_find_attr(node, "id");
     
    3837        if (!from) {
    3938                return XT_HANDLED; /* Consider this packet corrupted. */
     39
    4040        }
    41 
    42         /* try to detect hipchat's own version of self-messages */
    43         if (jd->flags & JFLAG_HIPCHAT) {
    44                 struct xt_node *c;
    45 
    46                 if ((c = xt_find_node_by_attr(node->children, "delay", "xmlns", XMLNS_DELAY)) &&
    47                     (s = xt_find_attr(c, "from_jid")) &&
    48                     jabber_compare_jid(s, jd->me)) {
    49                         carbons_sent = TRUE;
    50                 }
    51         }
    52 
    53         if (request && id && g_strcmp0(type, "groupchat") != 0 && !carbons_sent) {
     41        if (request && id) {
    5442                /* Send a message receipt (XEP-0184), looking like this:
    55                  * <message from='...' id='...' to='...'>
     43                 * <message
     44                 *  from='kingrichard@royalty.england.lit/throne'
     45                 *  id='bi29sg183b4v'
     46                 *  to='northumberland@shakespeare.lit/westminster'>
    5647                 *  <received xmlns='urn:xmpp:receipts' id='richard2-4.1.247'/>
    57                  * </message>
    58                  *
    59                  * MUC messages are excluded, since receipts aren't supposed to be sent over MUCs
    60                  * (XEP-0184 section 5.3) and replying to those may result in 'forbidden' errors.
    61                  */
     48                 * </message> */
    6249                struct xt_node *received, *receipt;
    6350
     
    140127                if (fullmsg->len > 0) {
    141128                        imcb_buddy_msg(ic, from, fullmsg->str,
    142                                        carbons_sent ? OPT_SELFMESSAGE : 0, jabber_get_timestamp(node));
     129                                       0, jabber_get_timestamp(node));
    143130                }
    144131                if (room) {
     
    149136
    150137                /* Handling of incoming typing notifications. */
    151                 if (bud == NULL || carbons_sent) {
    152                         /* Can't handle these for unknown buddies.
    153                            And ignore them if it's just carbons */
     138                if (bud == NULL) {
     139                        /* Can't handle these for unknown buddies. */
    154140                } else if (xt_find_node(node->children, "composing")) {
    155141                        bud->flags |= JBFLAG_DOES_XEP85;
    156142                        imcb_buddy_typing(ic, from, OPT_TYPING);
    157143                }
    158                 else if (xt_find_node(node->children, "active")) {
     144                /* No need to send a "stopped typing" signal when there's a message. */
     145                else if (xt_find_node(node->children, "active") && (body == NULL)) {
    159146                        bud->flags |= JBFLAG_DOES_XEP85;
    160 
    161                         /* No need to send a "stopped typing" signal when there's a message. */
    162                         if (body == NULL) {
    163                                 imcb_buddy_typing(ic, from, 0);
    164                         }
     147                        imcb_buddy_typing(ic, from, 0);
    165148                } else if (xt_find_node(node->children, "paused")) {
    166149                        bud->flags |= JBFLAG_DOES_XEP85;
     
    175158        return XT_HANDLED;
    176159}
    177 
    178 static xt_status jabber_carbons_message(struct xt_node *node, gpointer data)
    179 {
    180         struct im_connection *ic = data;
    181         struct xt_node *wrap, *fwd, *msg;
    182         gboolean carbons_sent;
    183 
    184         if ((wrap = xt_find_node(node->children, "received"))) {
    185                 carbons_sent = FALSE;
    186         } else if ((wrap = xt_find_node(node->children, "sent"))) {
    187                 carbons_sent = TRUE;
    188         }
    189 
    190         if (wrap == NULL || g_strcmp0(xt_find_attr(wrap, "xmlns"), XMLNS_CARBONS) != 0) {
    191                 return XT_NEXT;
    192         }
    193 
    194         if (!(fwd = xt_find_node(wrap->children, "forwarded")) ||
    195              (g_strcmp0(xt_find_attr(fwd, "xmlns"), XMLNS_FORWARDING) != 0) ||
    196             !(msg = xt_find_node(fwd->children, "message"))) {
    197                 imcb_log(ic, "Error: Invalid carbons message received");
    198                 return XT_ABORT;
    199         }
    200 
    201         return jabber_pkt_message_normal(msg, data, carbons_sent);
    202 }
    203 
    204 xt_status jabber_pkt_message(struct xt_node *node, gpointer data)
    205 {
    206         struct im_connection *ic = data;
    207         struct jabber_data *jd = ic->proto_data;
    208         char *from = xt_find_attr(node, "from");
    209 
    210         if (jabber_compare_jid(jd->me, from)) {    /* Probably a Carbons message */
    211                 xt_status st = jabber_carbons_message(node, data);
    212                 if (st == XT_HANDLED || st == XT_ABORT) {
    213                         return st;
    214                 }
    215         }
    216         return jabber_pkt_message_normal(node, data, FALSE);
    217 }
  • protocols/jabber/presence.c

    r3fbce97 r63cad66  
    186186        char *prio = set_getstr(&ic->acc->set, "priority");
    187187
    188         if (jd->away_state && jd->away_state->full_name != NULL) {
     188        if (jd->away_state->code != NULL) {
    189189                int new_prio = (atoi(prio) - 5);
    190190                if (new_prio < 0) {
     
    222222        cap = xt_new_node("c", NULL, NULL);
    223223        xt_add_attr(cap, "xmlns", XMLNS_CAPS);
    224 
    225         if (jd->flags & JFLAG_HIPCHAT) {
    226                 /* hipchat specific node, whitelisted by request to receive self-messages */
    227                 xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps/hipchat");
    228         } else {
    229                 xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps");
    230         }
     224        xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps");
    231225        xt_add_attr(cap, "ver", BITLBEE_VERSION);   /* The XEP wants this hashed, but nobody's doing that. */
    232226        xt_add_child(node, cap);
  • protocols/jabber/s5bytestream.c

    r3fbce97 r63cad66  
    536536                 * that sends atyp=0 addrlen=0 and only 6 bytes (one less than one would expect).
    537537                 * Therefore I removed the wait for more bytes. Since we don't care about what else the proxy
    538                  * is sending, it should not matter */
     538                 * is sending, it shouldnt matter */
    539539
    540540                if (bt->tf->ft->sending) {
     
    559559 * An intelligent sender would probably specify himself as the first streamhost and
    560560 * a proxy as the second (Kopete and PSI are examples here). That way, a (potentially)
    561  * slow proxy is only used if necessary. This of course also means, that the timeout
     561 * slow proxy is only used if neccessary. This of course also means, that the timeout
    562562 * per streamhost should be kept short. If one or two firewalled adresses are specified,
    563563 * they have to timeout first before a proxy is tried.
  • protocols/jabber/sasl.c

    r3fbce97 r63cad66  
    3838        "6C-Zgf7Tr7gEQTPlBhMUgo7R",
    3939};
     40const struct oauth2_service oauth2_service_facebook =
     41{
     42        "https://www.facebook.com/dialog/oauth",
     43        "https://graph.facebook.com/oauth/access_token",
     44        "https://www.bitlbee.org/main.php/Facebook/oauth2.html",
     45        "offline_access,xmpp_login",
     46        "126828914005625",
     47        "4b100f0f244d620bf3f15f8b217d4c32",
     48};
    4049
    4150xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data)
     
    4554        struct xt_node *c, *reply;
    4655        char *s;
    47         int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_anonymous = 0;
     56        int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0, sup_anonymous = 0;
    4857        int want_oauth = FALSE, want_hipchat = FALSE, want_anonymous = FALSE;
    4958        GString *mechs;
     
    8089                } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) {
    8190                        sup_gtalk = 1;
     91                } else if (c->text && g_strcasecmp(c->text, "X-FACEBOOK-PLATFORM") == 0) {
     92                        sup_fb = 1;
    8293                }
    8394
     
    90101
    91102        if (!want_oauth && !sup_plain && !sup_digest) {
    92                 if (!sup_gtalk) {
     103                if (!sup_gtalk && !sup_fb) {
    93104                        imcb_error(ic, "This server requires OAuth "
    94105                                   "(supported schemes:%s)", mechs->str);
     
    126137                reply->text_len = strlen(reply->text);
    127138                g_free(s);
     139        } else if (sup_fb && want_oauth) {
     140                xt_add_attr(reply, "mechanism", "X-FACEBOOK-PLATFORM");
     141                jd->flags |= JFLAG_SASL_FB;
    128142        } else if (want_oauth) {
    129143                imcb_error(ic, "OAuth requested, but not supported by server");
     
    140154                xt_free_node(reply);
    141155                return XT_ABORT;
    142         } else if (sup_digest && !(jd->ssl && sup_plain)) {
    143                 /* Only try DIGEST-MD5 if there's no SSL/TLS or if PLAIN isn't supported.
    144                  * Which in practice means "don't bother with DIGEST-MD5 most of the time".
    145                  * It's weak, pointless over TLS, and often breaks with some servers (hi openfire) */
    146 
     156        } else if (sup_digest) {
    147157                xt_add_attr(reply, "mechanism", "DIGEST-MD5");
    148158
     
    285295        dec = frombase64(node->text);
    286296
    287         if (!(s = sasl_get_part(dec, "rspauth"))) {
     297        if (jd->flags & JFLAG_SASL_FB) {
     298                /* New-style Facebook OAauth2 support. Instead of sending a refresh
     299                   token, they just send an access token that should never expire. */
     300                GSList *p_in = NULL, *p_out = NULL;
     301                char time[33];
     302
     303                oauth_params_parse(&p_in, dec);
     304                oauth_params_add(&p_out, "nonce", oauth_params_get(&p_in, "nonce"));
     305                oauth_params_add(&p_out, "method", oauth_params_get(&p_in, "method"));
     306                oauth_params_free(&p_in);
     307
     308                g_snprintf(time, sizeof(time), "%lld", (long long) (gettime() * 1000));
     309                oauth_params_add(&p_out, "call_id", time);
     310                oauth_params_add(&p_out, "api_key", oauth2_service_facebook.consumer_key);
     311                oauth_params_add(&p_out, "v", "1.0");
     312                oauth_params_add(&p_out, "format", "XML");
     313                oauth_params_add(&p_out, "access_token", jd->oauth2_access_token);
     314
     315                reply = oauth_params_string(p_out);
     316                oauth_params_free(&p_out);
     317        } else if (!(s = sasl_get_part(dec, "rspauth"))) {
    288318                /* See RFC 2831 for for information. */
    289319                md5_state_t A1, A2, H;
  • protocols/jabber/si.c

    r3fbce97 r63cad66  
    186186        jd->filetransfers = g_slist_prepend(jd->filetransfers, tf);
    187187
    188         /* query buddy's features and server's streaming proxies if necessary */
     188        /* query buddy's features and server's streaming proxies if neccessary */
    189189
    190190        if (!tf->bud->features) {
     
    283283
    284284        if (requestok) {
    285                 /* Figure out who the transfer should come from... */
     285                /* Figure out who the transfer should come frome... */
    286286
    287287                ext_jid = ini_jid;
     
    403403         * <iq from=... to=... id=...>
    404404         *      <si xmlns=si>
    405          *      [       <file xmlns=ft/>    ] <-- not necessary
     405         *      [       <file xmlns=ft/>    ] <-- not neccessary
    406406         *              <feature xmlns=feature>
    407407         *                      <x xmlns=xdata type=submit>
  • protocols/msn/gw.c

    r3fbce97 r63cad66  
    2222        gw->ssl = (GATEWAY_PORT == 443);
    2323        gw->poll_timeout = -1;
    24         gw->write_timeout = -1;
    2524        gw->ic = ic;
    2625        gw->md = ic->proto_data;
     
    3534                b_event_remove(gw->poll_timeout);
    3635        }
    37 
    38         if (gw->write_timeout != -1) {
    39                 b_event_remove(gw->write_timeout);
    40         }
    41 
    4236        g_byte_array_free(gw->in, TRUE);
    4337        g_byte_array_free(gw->out, TRUE);
     
    195189}
    196190
    197 static gboolean msn_gw_write_cb(gpointer data, gint source, b_input_condition cond)
     191void msn_gw_write(struct msn_gw *gw, char *buf, size_t len)
    198192{
    199         struct msn_gw *gw;
    200        
    201         if (!(gw = msn_gw_from_ic(data))) {
    202                 return FALSE;
    203         }
    204 
     193        g_byte_array_append(gw->out, (const guint8 *) buf, len);
    205194        if (!gw->open) {
    206195                msn_gw_open(gw);
     
    208197                msn_gw_dorequest(gw, NULL);
    209198        }
    210 
    211         gw->write_timeout = -1;
    212         return FALSE;
    213199}
    214 
    215 void msn_gw_write(struct msn_gw *gw, char *buf, size_t len)
    216 {
    217         g_byte_array_append(gw->out, (const guint8 *) buf, len);
    218 
    219         /* do a bit of buffering here to send several commands with a single request */
    220         if (gw->write_timeout == -1) {
    221                 gw->write_timeout = b_timeout_add(1, msn_gw_write_cb, gw->ic);
    222         }
    223 }
  • protocols/msn/msn.h

    r3fbce97 r63cad66  
    112112
    113113        int poll_timeout;
    114         int write_timeout;
    115114
    116115        b_event_handler callback;
  • protocols/msn/msn_util.c

    r3fbce97 r63cad66  
    4141        }
    4242
    43         return g_markup_printf_escaped("<ml><d n=\"%s\"><c n=\"%s\" t=\"1\"><s n=\"IM\" l=\"%d\" /></c></d></ml>",
     43        return g_markup_printf_escaped("<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>",
    4444                                       domain, handle, list);
    4545}
  • protocols/msn/ns.c

    r3fbce97 r63cad66  
    3939static void msn_ns_send_adl(struct im_connection *ic);
    4040static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd);
    41 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage);
     41static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action);
    4242static void msn_ns_nfy(struct msn_data *md, char *who, char **parts, char *action, gboolean is_put);
    4343
     
    110110        struct im_connection *ic = md->ic;
    111111
    112         /* this should be taken from XFR, but hardcoding it for now. it also prevents more redirects. */
    113         const char *redir_data = "VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDINCklzR2VvWGZyOiB0cnVlDQo=";
    114 
    115112        if (source == -1 && !md->is_http) {
    116113                imcb_error(ic, "Could not connect to server");
     
    138135        }
    139136
    140         /* Having to handle potential errors in each write sure makes these ifs awkward...*/
    141 
    142         if (msn_ns_write(ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER) &&
    143             msn_ns_write(ic, source, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s %s\r\n",
    144                          ++md->trId, ic->acc->user, redir_data) &&
    145             msn_ns_write(ic, md->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user)) {
    146 
     137        if (msn_ns_write(ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER)) {
    147138                if (!md->is_http) {
    148139                        md->inpa = b_input_add(md->fd, B_EV_IO_READ, msn_ns_callback, md);
     
    217208                }
    218209
     210                return(msn_ns_write(ic, md->fd, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDINClhmclNlbnRVVENUaW1lOiA2MzU2MTQ3OTU5NzgzOTAwMDANCklzR2VvWGZyOiB0cnVlDQo=\r\n",
     211                                    ++md->trId, ic->acc->user));
    219212        } else if (strcmp(cmd[0], "CVR") == 0) {
    220213                /* We don't give a damn about the information we just received */
     214                return msn_ns_write(ic, md->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user);
    221215        } else if (strcmp(cmd[0], "XFR") == 0) {
    222216                char *server;
     
    286280                        md->msglen = atoi(cmd[2]);
    287281                }
    288         } else if (strcmp(cmd[0], "RML") == 0) {
    289                 /* Move along, nothing to see here */
    290282        } else if (strcmp(cmd[0], "CHL") == 0) {
    291283                char *resp;
     
    483475}
    484476
    485 /* returns newly allocated string */
    486 static char *msn_ns_parse_header_address(struct msn_data *md, char *headers, char *header_name)
    487 {
     477static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd)
     478{
     479        char **parts = NULL;
    488480        char *semicolon = NULL;
    489         char *header = NULL;
    490         char *address = NULL;
    491 
    492         if (!(header = get_rfc822_header(headers, header_name, 0))) {
    493                 return NULL;
     481        char *action = NULL;
     482        char *from = NULL;
     483        char *who = NULL;
     484
     485        parts = g_strsplit(msg, "\r\n\r\n", 4);
     486
     487        if (!(from = get_rfc822_header(parts[0], "From", 0))) {
     488                goto cleanup;
    494489        }
    495490
    496491        /* either the semicolon or the end of the string */
    497         semicolon = strchr(header, ';') ? : (header + strlen(header));
    498 
    499         address = g_strndup(header + 2, semicolon - header - 2);
    500 
    501         g_free(header);
    502         return address;
    503 }
    504 
    505 static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd)
    506 {
    507         char **parts = NULL;
    508         char *action = NULL;
    509         char *who = NULL;
    510         gboolean selfmessage = FALSE;
    511 
    512         parts = g_strsplit(msg, "\r\n\r\n", 4);
    513 
    514         if (!(who = msn_ns_parse_header_address(md, parts[0], "From"))) {
    515                 goto cleanup;
    516         }
    517 
    518         if (strcmp(who, md->ic->acc->user) == 0) {
    519                 selfmessage = TRUE;
    520                 g_free(who);
    521                 if (!(who = msn_ns_parse_header_address(md, parts[0], "To"))) {
    522                         goto cleanup;
    523                 }
    524         }
     492        semicolon = strchr(from, ';') ? : (from + strlen(from));
     493
     494        who = g_strndup(from + 2, semicolon - from - 2);
    525495
    526496        if ((strcmp(cmd[0], "SDG") == 0) && (action = get_rfc822_header(parts[2], "Message-Type", 0))) {
    527                 msn_ns_sdg(md, who, parts, action, selfmessage);
     497                msn_ns_sdg(md, who, parts, action);
    528498
    529499        } else if ((strcmp(cmd[0], "NFY") == 0) && (action = get_rfc822_header(parts[2], "Uri", 0))) {
     
    535505        g_strfreev(parts);
    536506        g_free(action);
     507        g_free(from);
    537508        g_free(who);
    538509}
    539510
    540 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage)
     511static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action)
    541512{
    542513        struct im_connection *ic = md->ic;
    543514
    544         if (strcmp(action, "Control/Typing") == 0 && !selfmessage) {
     515        if (strcmp(action, "Control/Typing") == 0) {
    545516                imcb_buddy_typing(ic, who, OPT_TYPING);
    546517        } else if (strcmp(action, "Text") == 0) {
    547                 imcb_buddy_msg(ic, who, parts[3], selfmessage ? OPT_SELFMESSAGE : 0, 0);
     518                imcb_buddy_msg(ic, who, parts[3], 0, 0);
    548519        }
    549520}
     
    624595        } else {
    625596                imcb_error(ic, "Error during Passport authentication: %s", error);
    626 
    627                 /* don't reconnect with auth errors */
    628                 if (error && g_str_has_prefix(error, "wsse:FailedAuthentication")) {
    629                         imc_logout(ic, FALSE);
    630                 } else {
    631                         imc_logout(ic, TRUE);
    632                 }
     597                imc_logout(ic, TRUE);
    633598        }
    634599}
  • protocols/msn/soap.c

    r3fbce97 r63cad66  
    270270        struct im_connection *ic = soap_req->ic;
    271271        struct msn_data *md = ic->proto_data;
     272        char pass[MAX_PASSPORT_PWLEN + 1];
    272273
    273274        if (sd->redirect) {
     
    285286        }
    286287
     288        strncpy(pass, ic->acc->pass, MAX_PASSPORT_PWLEN);
     289        pass[MAX_PASSPORT_PWLEN] = '\0';
    287290        soap_req->payload = g_markup_printf_escaped(SOAP_PASSPORT_SSO_PAYLOAD,
    288                                                     ic->acc->user, ic->acc->pass, md->pp_policy);
     291                                                    ic->acc->user, pass, md->pp_policy);
    289292
    290293        return MSN_SOAP_OK;
     
    324327        struct xt_node *code = xt_find_node(node->children, "faultcode");
    325328        struct xt_node *string = xt_find_node(node->children, "faultstring");
    326         struct xt_node *reqstatus = xt_find_path(node, "psf:pp/psf:reqstatus");
    327329        struct xt_node *url;
    328330
     
    333335                   url->text_len > 0) {
    334336                sd->redirect = g_strdup(url->text);
    335         } else if (reqstatus && strcmp(reqstatus->text, "0x800488fe") == 0) {
    336                 char *msg = "Location blocked. Log in to live.com, go to recent activity and click 'this was me'";
    337                 sd->error = g_strdup_printf("%s (%s)", code->text, msg);
    338337        } else {
    339338                sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ?
     
    347346        { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", msn_soap_passport_sso_token },
    348347        { "S:Fault", "S:Envelope", msn_soap_passport_failure },
    349         { "S:Fault", "wst:RequestSecurityTokenResponse", msn_soap_passport_failure },
    350348        { NULL, NULL, NULL }
    351349};
     
    776774                imcb_log(soap_req->ic, "Warning: %d contacts were in both your "
    777775                         "block and your allow list. Assuming they're all "
    778                          "allowed.", wtf);
     776                         "allowed. Use the official WLM client once to fix "
     777                         "this.", wtf);
    779778        }
    780779
  • protocols/msn/soap.h

    r3fbce97 r63cad66  
    6161#define SOAP_PASSPORT_SSO_URL "https://login.live.com/RST.srf"
    6262#define SOAP_PASSPORT_SSO_URL_MSN "https://msnia.login.live.com/pp900/RST.srf"
     63#define MAX_PASSPORT_PWLEN 16
    6364
    6465#define SOAP_PASSPORT_SSO_PAYLOAD \
  • protocols/nogaim.c

    r3fbce97 r63cad66  
    9090
    9191GList *protocols = NULL;
    92 GList *disabled_protocols = NULL;
    9392
    9493void register_protocol(struct prpl *p)
     
    104103
    105104        if (refused) {
    106                 disabled_protocols = g_list_append(disabled_protocols, p);
     105                log_message(LOGLVL_WARNING, "Protocol %s disabled\n", p->name);
    107106        } else {
    108107                protocols = g_list_append(protocols, p);
     
    110109}
    111110
    112 static int proto_name_cmp(const void *proto_, const void *name)
    113 {
    114         const struct prpl *proto = proto_;
    115         return g_strcasecmp(proto->name, name);
    116 }
    117 
    118111struct prpl *find_protocol(const char *name)
    119112{
    120         GList *gl = g_list_find_custom(protocols, name, proto_name_cmp);
    121         return gl ? gl->data: NULL;
    122 }
    123 
    124 gboolean is_protocol_disabled(const char *name)
    125 {
    126         return g_list_find_custom(disabled_protocols, name, proto_name_cmp) != NULL;
     113        GList *gl;
     114
     115        for (gl = protocols; gl; gl = gl->next) {
     116                struct prpl *proto = gl->data;
     117
     118                if (g_strcasecmp(proto->name, name) == 0) {
     119                        return proto;
     120                }
     121        }
     122
     123        return NULL;
    127124}
    128125
     
    212209        account_t *a;
    213210
    214         if (!ic->bee->ui->log) {
    215                 return;
    216         }
    217 
    218211        va_start(params, format);
    219212        text = g_strdup_vprintf(format, params);
     
    234227        /* If we found one, include the screenname in the message. */
    235228        if (a) {
    236                 ic->bee->ui->log(ic->bee, ic->acc->tag, text);
     229                /* FIXME(wilmer): ui_log callback or so */
     230                irc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->tag, text);
    237231        } else {
    238                 ic->bee->ui->log(ic->bee, ic->acc->prpl->name, text);
     232                irc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text);
    239233        }
    240234
     
    668662                GList *m = ic->acc->prpl->away_states(ic);
    669663                msg = ic->acc->flags & ACC_FLAG_AWAY_MESSAGE ? away : NULL;
    670                 away = imc_away_state_find(m, away, &msg) ? :
    671                        (imc_away_state_find(m, "away", &msg) ? : m->data);
     664                away = imc_away_state_find(m, away, &msg) ? : m->data;
    672665        } else if (ic->acc->flags & ACC_FLAG_STATUS_MESSAGE) {
    673666                away = NULL;
     
    788781}
    789782
    790 /* Deprecated: using this function resulted in merging several handles accidentally
    791  * Also the irc layer handles this decently nowadays */
    792783void imcb_clean_handle(struct im_connection *ic, char *handle)
    793784{
    794 }
     785        /* Accepts a handle and does whatever is necessary to make it
     786           BitlBee-friendly. Currently this means removing everything
     787           outside 33-127 (ASCII printable excl spaces), @ (only one
     788           is allowed) and ! and : */
     789        char out[strlen(handle) + 1];
     790        int s, d;
     791
     792        s = d = 0;
     793        while (handle[s]) {
     794                if (handle[s] > ' ' && handle[s] != '!' && handle[s] != ':' &&
     795                    (handle[s] & 0x80) == 0) {
     796                        if (handle[s] == '@') {
     797                                /* See if we got an @ already? */
     798                                out[d] = 0;
     799                                if (strchr(out, '@')) {
     800                                        continue;
     801                                }
     802                        }
     803
     804                        out[d++] = handle[s];
     805                }
     806                s++;
     807        }
     808        out[d] = handle[s];
     809
     810        strcpy(handle, out);
     811}
  • protocols/nogaim.h

    r3fbce97 r63cad66  
    7676#define OPT_PONGED      0x00020000 /* Received a keep-alive during last interval */
    7777#define OPT_LOCAL_CONTACTS_SENT 0x00040000 /* Protocol already requested local contact list, so don't send it after finishing login. */
    78 #define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */
    7978
    8079/* ok. now the fun begins. first we create a connection structure */
     
    281280G_MODULE_EXPORT GSList *get_connections();
    282281G_MODULE_EXPORT struct prpl *find_protocol(const char *name);
    283 G_MODULE_EXPORT gboolean is_protocol_disabled(const char *name);
    284282/* When registering a new protocol, you should allocate space for a new prpl
    285283 * struct, initialize it (set the function pointers to point to your
     
    328326G_MODULE_EXPORT void imcb_add_buddy(struct im_connection *ic, const char *handle, const char *group);
    329327G_MODULE_EXPORT void imcb_remove_buddy(struct im_connection *ic, const char *handle, char *group);
     328G_MODULE_EXPORT struct buddy *imcb_find_buddy(struct im_connection *ic, char *handle);
    330329G_MODULE_EXPORT void imcb_rename_buddy(struct im_connection *ic, const char *handle, const char *realname);
    331330G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick);
     
    333332G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic);
    334333
    335 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags);
     334G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags);
    336335G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle(struct im_connection *ic, const char *handle);
    337 
    338 G_GNUC_DEPRECATED G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle);
     336G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle);
    339337
    340338/* Actions, or whatever. */
  • protocols/oscar/aim.h

    r3fbce97 r63cad66  
    2121
    2222#include "bitlbee.h"
    23 
    24 #ifdef WITH_PURPLE
    25 /* For compatibility with builds that include both purple and this oscar module */
    26 #include "aim_prefixes.h"
    27 #endif
    2823
    2924/* XXX adjust these based on autoconf-detected platform */
     
    876871 * SNAC Family: Internal Messages
    877872 *
    878  * This isn't truly a SNAC family either, but using
     873 * This isn't truely a SNAC family either, but using
    879874 * these, we can integrated non-SNAC services into
    880875 * the SNAC-centered libfaim callback structure.
  • protocols/oscar/auth.c

    r3fbce97 r63cad66  
    4141 * meaning you generally never call this.
    4242 *
    43  * But there are times when something might want it separate. Specifically,
     43 * But there are times when something might want it seperate. Specifically,
    4444 * libfaim sends this internally when doing SNAC login.
    4545 *
  • protocols/oscar/conn.c

    r3fbce97 r63cad66  
    1515 * In OSCAR, every connection has a set of SNAC groups associated
    1616 * with it.  These are the groups that you can send over this connection
    17  * without being guaranteed a "Not supported" SNAC error.
     17 * without being guarenteed a "Not supported" SNAC error.
    1818 *
    1919 * The grand theory of things says that these associations transcend
     
    3636 *
    3737 * Here comes the good bit.  Without even letting anyone know, particularly
    38  * the module that decided to send this SNAC, and definitely not that twit
     38 * the module that decided to send this SNAC, and definitly not that twit
    3939 * in Greenland, you send out a service request.  In this request, you have
    4040 * marked the need for a connection supporting group 0x000e.  A few seconds
     
    317317
    318318        if (deadconn->fd >= 3) {
    319                 proxy_disconnect(deadconn->fd);
     319                closesocket(deadconn->fd);
    320320        }
    321321        deadconn->fd = -1;
  • protocols/oscar/im.c

    r3fbce97 r63cad66  
    5050 * encoding for your message.  In UNICODE mode, _all_ characters must
    5151 * occupy 16bits, including ones that are not special.  (Remember that
    52  * the first 128 UNICODE symbols are equivalent to ASCII7, however they
     52 * the first 128 UNICODE symbols are equivelent to ASCII7, however they
    5353 * must be prefixed with a zero high order byte.)
    5454 *
     
    6464 * in all of libfaim, it is written with performance in mind.  As such,
    6565 * it is not as clear as it could be in respect to how this message is
    66  * supposed to be laid out. Most obviously, tlvlists should be used
     66 * supposed to be layed out. Most obviously, tlvlists should be used
    6767 * instead of writing out the bytes manually.
    6868 *
     
    476476 * examples of how to do this.
    477477 *
    478  * I would definitely recommend avoiding this feature unless you really
     478 * I would definitly recommend avoiding this feature unless you really
    479479 * know what you are doing, and/or you have something neat to do with it.
    480480 *
     
    638638                        }
    639639#if 0
    640                         /* XXX this isn't really necessary... */
     640                        /* XXX this isn't really necesary... */
    641641                        if (((args.flag1 != 0x0000) &&
    642642                             (args.flag1 != 0x0002) &&
     
    11611161         *
    11621162         * Channel 0x0001 is the message channel.  There are
    1163          * other channels for things called "rendezvous"
     1163         * other channels for things called "rendevous"
    11641164         * which represent chat and some of the other new
    11651165         * features of AIM2/3/3.5.
    11661166         *
    1167          * Channel 0x0002 is the Rendezvous channel, which
     1167         * Channel 0x0002 is the Rendevous channel, which
    11681168         * is where Chat Invitiations and various client-client
    11691169         * connection negotiations come from.
     
    11811181         * with the TLVs read below, they are two different pieces.  The
    11821182         * userinfo block contains the number of TLVs that contain user
    1183          * information, the rest are not even though there is no separation.
     1183         * information, the rest are not even though there is no seperation.
    11841184         * aim_extractuserinfo() returns the number of bytes used by the
    11851185         * userinfo tlvs, so you can start reading the rest of them right
     
    12531253/*
    12541254 *
    1255  * I definitely recommend sending this.  If you don't, you'll be stuck
     1255 * I definitly recommend sending this.  If you don't, you'll be stuck
    12561256 * with the rather unreasonable defaults.  You don't want those.  Send this.
    12571257 *
  • protocols/oscar/misc.c

    r3fbce97 r63cad66  
    33 * aim_misc.c
    44 *
    5  * TODO: Separate a lot of this into an aim_bos.c.
     5 * TODO: Seperate a lot of this into an aim_bos.c.
    66 *
    77 * Other things...
  • protocols/oscar/msgcookie.c

    r3fbce97 r63cad66  
    142142 * @cookiep: the address of a pointer to the cookie struct to remove
    143143 *
    144  * this function removes the cookie *cookie from the list of cookies
     144 * this function removes the cookie *cookie from teh list of cookies
    145145 * in sess, and then frees all memory associated with it. including
    146146 * its data! if you want to use the private data after calling this,
  • protocols/oscar/oscar.c

    r3fbce97 r63cad66  
    12661266        } break;
    12671267
    1268         case 2: {         /* rendezvous */
     1268        case 2: {         /* rendevous */
    12691269                struct aim_incomingim_ch2_args *args;
    12701270                args = va_arg(ap, struct aim_incomingim_ch2_args *);
  • protocols/oscar/rxhandlers.c

    r3fbce97 r63cad66  
    381381        /*
    382382         * This doesn't have to be called here.  It could easily be done
    383          * by a separate thread or something. It's an administrative operation,
     383         * by a seperate thread or something. It's an administrative operation,
    384384         * and can take a while. Though the less you call it the less memory
    385385         * you'll have :)
  • protocols/oscar/rxqueue.c

    r3fbce97 r63cad66  
    361361/*
    362362 * Grab a single command sequence off the socket, and enqueue
    363  * it in the incoming event queue in a separate struct.
     363 * it in the incoming event queue in a seperate struct.
    364364 */
    365365int aim_get_command(aim_session_t *sess, aim_conn_t *conn)
     
    479479
    480480/*
    481  * Purge receive queue of all handled commands (->handled==1).  Also
     481 * Purge recieve queue of all handled commands (->handled==1).  Also
    482482 * allows for selective freeing using ->nofree so that the client can
    483483 * keep the data for various purposes.
  • protocols/oscar/service.c

    r3fbce97 r63cad66  
    157157
    158158/*
    159  * OSCAR defines several 'rate classes'.  Each class has separate
     159 * OSCAR defines several 'rate classes'.  Each class has seperate
    160160 * rate limiting properties (limit level, alert level, disconnect
    161161 * level, etc), and a set of SNAC family/type pairs associated with
     
    709709 * of memory.  (I won't put it past them to start requesting data in
    710710 * less static regions -- regions that are initialized at run time, but still
    711  * before the client receives this request.)
    712  *
    713  * When the client receives the request, it adds it to the current ds
     711 * before the client recieves this request.)
     712 *
     713 * When the client recieves the request, it adds it to the current ds
    714714 * (0x00400000) and dereferences it, copying the data into a buffer which
    715715 * it then runs directly through the MD5 hasher.  The 16 byte output of
     
    723723 *     download a FREE, fully featured, and authorized client, here
    724724 *     http://www.aol.com/aim/download2.html"
    725  * The connection is then closed, receiving disconnect code 1, URL
     725 * The connection is then closed, recieving disconnect code 1, URL
    726726 * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html.
    727727 *
    728728 * Note, however, that numerous inconsistencies can cause the above error,
    729  * not just sending back a bad hash.  Do not immediately suspect this code
     729 * not just sending back a bad hash.  Do not immediatly suspect this code
    730730 * if you get disconnected.  AOL and the open/free software community have
    731731 * played this game for a couple years now, generating the above message
    732  * on numerous occasions.
     732 * on numerous ocassions.
    733733 *
    734734 * Anyway, neener.  We win again.
  • protocols/oscar/tlv.c

    r3fbce97 r63cad66  
    2525 * bstream references, so that at least the ->value portion of each
    2626 * element doesn't need to be malloc/memcpy'd.  This could prove to be
    27  * just as efficient as the in-place TLV parsing used in a couple places
     27 * just as effecient as the in-place TLV parsing used in a couple places
    2828 * in libfaim.
    2929 *
     
    135135/**
    136136 * aim_addtlvtochain_str - Add a string to a TLV chain
    137  * @list: Designation chain (%NULL pointer if empty)
     137 * @list: Desination chain (%NULL pointer if empty)
    138138 * @type: TLV type
    139139 * @str: String to add
  • protocols/oscar/txqueue.c

    r3fbce97 r63cad66  
    6767 * The overall purpose here is to enqueue the passed in command struct
    6868 * into the outgoing (tx) queue.  Basically...
    69  *   1) Make a scope-irrelevant copy of the struct
     69 *   1) Make a scope-irrelevent copy of the struct
    7070 *   3) Mark as not-sent-yet
    7171 *   4) Enqueue the struct into the list
  • protocols/purple/ft-direct.c

    r3fbce97 r63cad66  
    193193PurpleXferUiOps bee_xfer_uiops =
    194194{
    195         prplcb_xfer_new,           /* new_xfer */
    196         prplcb_xfer_dbg,           /* destroy */
    197         prplcb_xfer_dbg,           /* add_xfer */
    198         prplcb_xfer_progress,      /* update_progress */
    199         prplcb_xfer_dbg,           /* cancel_local */
    200         prplcb_xfer_dbg,           /* cancel_remote */
    201         prplcb_xfer_write,         /* ui_write */
    202         prplcb_xfer_read,          /* ui_read */
    203         prplcb_xfer_dbg,           /* data_not_sent */
     195        prplcb_xfer_new,
     196        prplcb_xfer_dbg,
     197        prplcb_xfer_dbg,
     198        prplcb_xfer_progress,
     199        prplcb_xfer_dbg,
     200        prplcb_xfer_dbg,
     201        prplcb_xfer_write,
     202        prplcb_xfer_read,
     203        prplcb_xfer_dbg,
    204204};
    205205
  • protocols/purple/ft.c

    r3fbce97 r63cad66  
    232232}
    233233
     234static void prplcb_xfer_dbg(PurpleXfer *xfer)
     235{
     236        fprintf(stderr, "prplcb_xfer_dbg 0x%p\n", xfer);
     237}
     238
    234239
    235240/* Sending files (UI->IM): */
     
    332337PurpleXferUiOps bee_xfer_uiops =
    333338{
    334         prplcb_xfer_new,           /* new_xfer */
    335         prplcb_xfer_destroy,       /* destroy */
    336         NULL,                      /* add_xfer */
    337         prplcb_xfer_progress,      /* update_progress */
    338         NULL,                      /* cancel_local */
    339         prplcb_xfer_cancel_remote, /* cancel_remote */
    340         NULL,                      /* ui_write */
    341         NULL,                      /* ui_read */
    342         NULL,                      /* data_not_sent */
     339        prplcb_xfer_new,
     340        prplcb_xfer_destroy,
     341        NULL, /* prplcb_xfer_add, */
     342        prplcb_xfer_progress,
     343        prplcb_xfer_dbg,
     344        prplcb_xfer_cancel_remote,
     345        NULL,
     346        NULL,
     347        prplcb_xfer_dbg,
    343348};
  • protocols/purple/purple.c

    r3fbce97 r63cad66  
    113113           servers anyway! */
    114114        if (!dir_fixed) {
    115                 PurpleCertificatePool *pool;
    116115                irc_t *irc = acc->bee->ui_data;
    117116                char *dir;
     
    123122                purple_blist_load();
    124123                purple_prefs_load();
    125 
    126                 if (proxytype == PROXY_SOCKS4A) {
    127                         /* do this here after loading prefs. yes, i know, it sucks */
    128                         purple_prefs_set_bool("/purple/proxy/socks4_remotedns", TRUE);
    129                 }
    130 
    131                 /* re-create the certificate cache directory */
    132                 pool = purple_certificate_find_pool("x509", "tls_peers");
    133                 dir = purple_certificate_pool_mkpath(pool, NULL);
    134                 purple_build_dir(dir, 0700);
    135                 g_free(dir);
    136 
    137124                dir_fixed = TRUE;
    138125        }
     
    365352        if (!pd) {
    366353                return;
    367         }
    368 
    369         while (ic->groupchats) {
    370                 imcb_chat_free(ic->groupchats->data);
    371354        }
    372355
     
    656639        /* Call the fucker. */
    657640        callback = (void *) mi->callback;
    658         callback(&pb->node, mi->data);
     641        callback(&pb->node, menu->data);
    659642
    660643        return NULL;
     
    724707                        g_hash_table_replace(chat_hash, "passwd", g_strdup(password));
    725708                }
    726 
    727                 g_free(pce);
    728         }
    729 
    730         g_list_free(info);
     709        }
    731710
    732711        serv_join_chat(purple_account_get_connection(pd->account), chat_hash);
    733712
    734         g_hash_table_destroy(chat_hash);
    735 
    736         return imcb_chat_new(ic, room);
     713        return NULL;
    737714}
    738715
     
    756733static PurpleCoreUiOps bee_core_uiops =
    757734{
    758         NULL,                      /* ui_prefs_init */
    759         NULL,                      /* debug_ui_init */
    760         purple_ui_init,            /* ui_init */
    761         NULL,                      /* quit */
    762         prplcb_ui_info,            /* get_ui_info */
     735        NULL,
     736        NULL,
     737        purple_ui_init,
     738        NULL,
     739        prplcb_ui_info,
    763740};
    764741
     
    787764        purple_gg_buddylist_import(gc);
    788765
    789         ic->flags |= OPT_DOES_HTML;
     766        if (gc->flags & PURPLE_CONNECTION_HTML) {
     767                ic->flags |= OPT_DOES_HTML;
     768        }
    790769}
    791770
     
    821800static PurpleConnectionUiOps bee_conn_uiops =
    822801{
    823         prplcb_conn_progress,                    /* connect_progress */
    824         prplcb_conn_connected,                   /* connected */
    825         prplcb_conn_disconnected,                /* disconnected */
    826         prplcb_conn_notice,                      /* notice */
    827         NULL,                                    /* report_disconnect */
    828         NULL,                                    /* network_connected */
    829         NULL,                                    /* network_disconnected */
    830         prplcb_conn_report_disconnect_reason,    /* report_disconnect_reason */
     802        prplcb_conn_progress,
     803        prplcb_conn_connected,
     804        prplcb_conn_disconnected,
     805        prplcb_conn_notice,
     806        NULL,
     807        NULL,
     808        NULL,
     809        prplcb_conn_report_disconnect_reason,
    831810};
    832811
     
    903882static PurpleBlistUiOps bee_blist_uiops =
    904883{
    905         NULL,                      /* new_list */
    906         prplcb_blist_new,          /* new_node */
    907         NULL,                      /* show */
    908         prplcb_blist_update,       /* update */
    909         prplcb_blist_remove,       /* remove */
     884        NULL,
     885        prplcb_blist_new,
     886        NULL,
     887        prplcb_blist_update,
     888        prplcb_blist_remove,
    910889};
    911890
     
    916895                struct groupchat *gc;
    917896
    918                 gc = bee_chat_by_title(ic->bee, ic, conv->name);
    919 
    920                 if (!gc) {
    921                         gc = imcb_chat_new(ic, conv->name);
    922                         if (conv->title != NULL) {
    923                                 imcb_chat_name_hint(gc, conv->title);
    924                         }
    925                 }
    926 
    927                 /* don't set the topic if it's just the name */
    928                 if (conv->title != NULL && strcmp(conv->name, conv->title) != 0) {
     897                gc = imcb_chat_new(ic, conv->name);
     898                if (conv->title != NULL) {
     899                        imcb_chat_name_hint(gc, conv->title);
    929900                        imcb_chat_topic(gc, NULL, conv->title, 0);
    930901                }
     
    969940}
    970941
    971 /* Generic handler for IM or chat messages, covers write_chat, write_im and write_conv */
    972 static void handle_conv_msg(PurpleConversation *conv, const char *who, const char *message, guint32 bee_flags, time_t mtime)
    973 {
    974         struct im_connection *ic = purple_ic_by_pa(conv->account);
     942void prplcb_conv_chat_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags,
     943                          time_t mtime)
     944{
    975945        struct groupchat *gc = conv->ui_data;
    976946        PurpleBuddy *buddy;
     947
     948        /* ..._SEND means it's an outgoing message, no need to echo those. */
     949        if (flags & PURPLE_MESSAGE_SEND) {
     950                return;
     951        }
    977952
    978953        buddy = purple_find_buddy(conv->account, who);
     
    981956        }
    982957
    983         if (conv->type == PURPLE_CONV_TYPE_IM) {
    984                 imcb_buddy_msg(ic, (char *) who, (char *) message, bee_flags, mtime);
    985         } else if (gc) {
    986                 imcb_chat_msg(gc, who, (char *) message, bee_flags, mtime);
    987         }
    988 }
    989 
    990 /* Handles write_im and write_chat. Removes echoes of locally sent messages */
    991 static void prplcb_conv_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime)
    992 {
    993         if (!(flags & PURPLE_MESSAGE_SEND)) {
    994                 handle_conv_msg(conv, who, message, 0, mtime);
    995         }
    996 }
    997 
    998 /* Handles write_conv. Only passes self messages from other locations through.
    999  * That is, only writes of PURPLE_MESSAGE_SEND.
    1000  * There are more events which might be handled in the future, but some are tricky.
    1001  * (images look like <img id="123">, what do i do with that?) */
    1002 static void prplcb_conv_write(PurpleConversation *conv, const char *who, const char *alias, const char *message,
    1003                               PurpleMessageFlags flags, time_t mtime)
    1004 {
     958        imcb_chat_msg(gc, who, (char *) message, 0, mtime);
     959}
     960
     961static void prplcb_conv_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags,
     962                           time_t mtime)
     963{
     964        struct im_connection *ic = purple_ic_by_pa(conv->account);
     965        PurpleBuddy *buddy;
     966
     967        /* ..._SEND means it's an outgoing message, no need to echo those. */
    1005968        if (flags & PURPLE_MESSAGE_SEND) {
    1006                 handle_conv_msg(conv, who, message, OPT_SELFMESSAGE, mtime);
    1007         }
     969                return;
     970        }
     971
     972        buddy = purple_find_buddy(conv->account, who);
     973        if (buddy != NULL) {
     974                who = purple_buddy_get_name(buddy);
     975        }
     976
     977        imcb_buddy_msg(ic, (char *) who, (char *) message, 0, mtime);
    1008978}
    1009979
     
    10381008        prplcb_conv_new,           /* create_conversation  */
    10391009        prplcb_conv_free,          /* destroy_conversation */
    1040         prplcb_conv_msg,           /* write_chat           */
    1041         prplcb_conv_msg,           /* write_im             */
    1042         prplcb_conv_write,         /* write_conv           */
     1010        prplcb_conv_chat_msg,      /* write_chat           */
     1011        prplcb_conv_im,            /* write_im             */
     1012        NULL,                      /* write_conv           */
    10431013        prplcb_conv_add_users,     /* chat_add_users       */
    10441014        NULL,                      /* chat_rename_user     */
     
    12051175static PurpleRequestUiOps bee_request_uiops =
    12061176{
    1207         prplcb_request_input,      /* request_input */
    1208         NULL,                      /* request_choice */
    1209         prplcb_request_action,     /* request_action */
    1210         NULL,                      /* request_fields */
    1211         NULL,                      /* request_file */
    1212         prplcb_close_request,      /* close_request */
    1213         NULL,                      /* request_folder */
     1177        prplcb_request_input,
     1178        NULL,
     1179        prplcb_request_action,
     1180        NULL,
     1181        NULL,
     1182        prplcb_close_request,
     1183        NULL,
    12141184};
    12151185
     
    12521222static PurplePrivacyUiOps bee_privacy_uiops =
    12531223{
    1254         prplcb_privacy_permit_added,       /* permit_added */
    1255         prplcb_privacy_permit_removed,     /* permit_removed */
    1256         prplcb_privacy_deny_added,         /* deny_added */
    1257         prplcb_privacy_deny_removed,       /* deny_removed */
     1224        prplcb_privacy_permit_added,
     1225        prplcb_privacy_permit_removed,
     1226        prplcb_privacy_deny_added,
     1227        prplcb_privacy_deny_removed,
    12581228};
    12591229
     
    12651235static PurpleDebugUiOps bee_debug_uiops =
    12661236{
    1267         prplcb_debug_print,        /* print */
     1237        prplcb_debug_print,
    12681238};
    12691239
     
    12861256static PurpleEventLoopUiOps glib_eventloops =
    12871257{
    1288         prplcb_ev_timeout_add,     /* timeout_add */
    1289         prplcb_ev_remove,          /* timeout_remove */
    1290         prplcb_ev_input_add,       /* input_add */
    1291         prplcb_ev_remove,          /* input_remove */
     1258        prplcb_ev_timeout_add,
     1259        prplcb_ev_remove,
     1260        prplcb_ev_input_add,
     1261        prplcb_ev_remove,
    12921262};
    1293 
    1294 /* Absolutely no connection context at all. Thanks purple! brb crying */
    1295 static void *prplcb_notify_message(PurpleNotifyMsgType type, const char *title,
    1296                                    const char *primary, const char *secondary)
    1297 {
    1298         char *text = g_strdup_printf("%s%s - %s%s%s",
    1299                 (type == PURPLE_NOTIFY_MSG_ERROR) ? "Error: " : "",
    1300                 title,
    1301                 primary ?: "",
    1302                 (primary && secondary) ? " - " : "",
    1303                 secondary ?: ""
    1304         );
    1305 
    1306         if (local_bee->ui->log) {
    1307                 local_bee->ui->log(local_bee, "purple", text);
    1308         }
    1309 
    1310         g_free(text);
    1311 
    1312         return NULL;
    1313 }
    13141263
    13151264static void *prplcb_notify_email(PurpleConnection *gc, const char *subject, const char *from,
     
    13731322static PurpleNotifyUiOps bee_notify_uiops =
    13741323{
    1375         prplcb_notify_message,     /* notify_message */
    1376         prplcb_notify_email,       /* notify_email */
    1377         NULL,                      /* notify_emails */
    1378         NULL,                      /* notify_formatted */
    1379         NULL,                      /* notify_searchresults */
    1380         NULL,                      /* notify_searchresults_new_rows */
    1381         prplcb_notify_userinfo,    /* notify_userinfo */
     1324        NULL,
     1325        prplcb_notify_email,
     1326        NULL,
     1327        NULL,
     1328        NULL,
     1329        NULL,
     1330        prplcb_notify_userinfo,
    13821331};
    13831332
     
    14061355static PurpleAccountUiOps bee_account_uiops =
    14071356{
    1408         NULL,                              /* notify_added */
    1409         NULL,                              /* status_changed */
    1410         NULL,                              /* request_add */
    1411         prplcb_account_request_authorize,  /* request_authorize */
    1412         NULL,                              /* close_account_request */
     1357        NULL,
     1358        NULL,
     1359        NULL,
     1360        prplcb_account_request_authorize,
     1361        NULL,
    14131362};
    14141363
     
    14381387        char *dir;
    14391388
    1440         g_assert((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ);
    1441         g_assert((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE);
     1389        if (B_EV_IO_READ != PURPLE_INPUT_READ ||
     1390            B_EV_IO_WRITE != PURPLE_INPUT_WRITE) {
     1391                /* FIXME FIXME FIXME FIXME FIXME :-) */
     1392                exit(1);
     1393        }
    14421394
    14431395        dir = g_strdup_printf("%s/purple", global.conf->configdir);
     
    14571409                PurpleProxyInfo *pi = purple_global_proxy_get_info();
    14581410                switch (proxytype) {
    1459                 case PROXY_SOCKS4A:
    14601411                case PROXY_SOCKS4:
    14611412                        purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS4);
  • protocols/skype/README

    r3fbce97 r63cad66  
    203203
    204204  * `account skype set skypeconsole_receive true` will make the
    205     `skypeconsole` account dump all the received raw traffic for you
     205    `skypeconsole` account dump all the recieved raw traffic for you
    206206
    207207- If you want to automatically join bookmarked groupchats right after
  • protocols/skype/skype.c

    r3fbce97 r63cad66  
    2121
    2222#define _XOPEN_SOURCE
     23#define _BSD_SOURCE
    2324#include <poll.h>
    2425#include <stdio.h>
     
    187188
    188189        va_start(args, fmt);
    189         g_vsnprintf(str, IRC_LINE_SIZE, fmt, args);
     190        vsnprintf(str, IRC_LINE_SIZE, fmt, args);
    190191        va_end(args);
    191192
     
    321322        }
    322323        return NULL;
    323 }
    324 
    325 static struct groupchat *skype_chat_get_or_create(struct im_connection *ic, char *id)
    326 {
    327         struct skype_data *sd = ic->proto_data;
    328         struct groupchat *gc = bee_chat_by_title(ic->bee, ic, id);
    329 
    330         if (!gc) {
    331                 gc = imcb_chat_new(ic, id);
    332                 imcb_chat_name_hint(gc, id);
    333                 imcb_chat_add_buddy(gc, sd->username);
    334 
    335                 skype_printf(ic, "GET CHAT %s ADDER\n", id);
    336                 skype_printf(ic, "GET CHAT %s TOPIC\n", id);
    337                 skype_printf(ic, "GET CHAT %s ACTIVEMEMBERS\n", id);
    338         }
    339 
    340         return gc;
    341324}
    342325
     
    705688                info += 9;
    706689                if (sd->handle && sd->body && sd->type) {
    707                         struct groupchat *gc = skype_chat_get_or_create(ic, info);
     690                        struct groupchat *gc = bee_chat_by_title(ic->bee, ic, info);
    708691                        int i;
    709692                        for (i = 0; i < g_list_length(sd->body); i++) {
     
    10431026        }
    10441027        if (!strcmp(info, "STATUS MULTI_SUBSCRIBED")) {
    1045                 skype_chat_get_or_create(ic, id);
     1028                gc = bee_chat_by_title(ic->bee, ic, id);
     1029                if (!gc) {
     1030                        gc = imcb_chat_new(ic, id);
     1031                        imcb_chat_name_hint(gc, id);
     1032                }
     1033                skype_printf(ic, "GET CHAT %s ADDER\n", id);
     1034                skype_printf(ic, "GET CHAT %s TOPIC\n", id);
    10461035        } else if (!strcmp(info, "STATUS DIALOG") && sd->groupchat_with) {
    1047                 gc = skype_chat_get_or_create(ic, id);
     1036                gc = imcb_chat_new(ic, id);
     1037                imcb_chat_name_hint(gc, id);
    10481038                /* According to the docs this
    10491039                 * is necessary. However it
     
    10561046                           sd->groupchat_with);
    10571047                imcb_chat_add_buddy(gc, buf);
     1048                imcb_chat_add_buddy(gc, sd->username);
    10581049                g_free(sd->groupchat_with);
    10591050                sd->groupchat_with = NULL;
     1051                skype_printf(ic, "GET CHAT %s ADDER\n", id);
     1052                skype_printf(ic, "GET CHAT %s TOPIC\n", id);
    10601053        } else if (!strcmp(info, "STATUS UNSUBSCRIBED")) {
    10611054                gc = bee_chat_by_title(ic->bee, ic, id);
     
    12641257                }
    12651258                g_strfreev(lines);
    1266         } else if (st == 0 || (st < 0 && !ssl_sockerr_again(sd->ssl))) {
     1259        } else if (st == 0 || (st < 0 && !sockerr_again())) {
    12671260                ssl_disconnect(sd->ssl);
    12681261                sd->fd = -1;
  • protocols/skype/t/add-yes-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/added-no-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/added-yes-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/away-set-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/call-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :alice
  • protocols/skype/t/call-failed-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :alice
  • protocols/skype/t/called-no-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/called-yes-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/ctcp-help-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/filetransfer-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/group-add-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/group-read-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/groupchat-invite-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
     
    77>> :bob!bob@skype.com JOIN :&bitlbee
    88<< PRIVMSG &bitlbee :chat with bob
    9 >> 353 alice = ##alice/$bob;a7ab206ec78 :@alice @root
    10 << INVITE cecil ##alice/$bob;a7ab206ec78
    11 >> cecil@skype.com JOIN :##alice/$bob;a7ab206ec78
     9>> 353 alice = ##alice/$bob;a7ab206ec780 :@alice bob @root
     10<< INVITE cecil ##alice/$bob;a7ab206ec780
     11>> cecil@skype.com JOIN :##alice/$bob;a7ab206ec780
  • protocols/skype/t/groupchat-invite-skyped.mock

    r3fbce97 r63cad66  
    2626>> GET CHAT #alice/$bob;a7ab206ec78060f1 TOPIC
    2727<< CHAT #alice/$bob;a7ab206ec78060f1 TOPIC
    28 >> GET CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS
    29 << CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS
    3028<< CHATMESSAGE 206 STATUS SENDING
    3129<< CHAT #alice/$bob;a7ab206ec78060f1 STATUS DIALOG
  • protocols/skype/t/groupchat-invited-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
     
    55<< PRIVMSG &bitlbee :account add skype alice foo
    66<< PRIVMSG &bitlbee :account skype on
    7 >> JOIN :##cecil/$bob;4d8cc996579
    8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root
     7>> JOIN :##cecil/$bob;4d8cc9965791
     8>> 353 alice = ##cecil/$bob;4d8cc9965791 :@alice bob cecil @root
  • protocols/skype/t/groupchat-leave-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
     
    66<< PRIVMSG &bitlbee :account skype set skypeconsole_receive true
    77<< PRIVMSG &bitlbee :account skype on
    8 >> JOIN :##cecil/$bob;4d8cc996579
    9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root
    10 << PART ##cecil/$bob;4d8cc996579
     8>> JOIN :##cecil/$bob;4d8cc9965791
     9>> 353 alice = ##cecil/$bob;4d8cc9965791 :@alice bob cecil @root
     10<< PART ##cecil/$bob;4d8cc9965791
    1111>> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 STATUS UNSUBSCRIBED
  • protocols/skype/t/groupchat-leave-skyped.mock

    r3fbce97 r63cad66  
    3636>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
    3737<< CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
    38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS
    39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS
     38>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER
     39<< CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob
     40>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
     41<< CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
     42>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER
     43<< CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob
     44>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
     45<< CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
    4046>> GET CHATMESSAGE 188 FROM_HANDLE
    4147<< CHATMESSAGE 188 FROM_HANDLE bob
  • protocols/skype/t/groupchat-msg-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
     
    66<< PRIVMSG &bitlbee :account skype set skypeconsole_receive true
    77<< PRIVMSG &bitlbee :account skype on
    8 >> JOIN :##cecil/$bob;4d8cc996579
    9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root
    10 << PRIVMSG ##cecil/$bob;4d8cc996579 :hello
     8>> JOIN :##cecil/$bob;4d8cc9965791
     9>> 353 alice = ##cecil/$bob;4d8cc9965791 :@alice bob cecil @root
     10<< PRIVMSG ##cecil/$bob;4d8cc9965791 :hello
    1111>> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVITY_TIMESTAMP
  • protocols/skype/t/groupchat-msg-skyped.mock

    r3fbce97 r63cad66  
    3636>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
    3737<< CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
    38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS
    39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS bob cecil alice
     38>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER
     39<< CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob
     40>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
     41<< CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
     42>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER
     43<< CHAT #cecil/$bob;4d8cc9965791c6b9 ADDER bob
     44>> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
     45<< CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC
    4046>> GET CHATMESSAGE 188 FROM_HANDLE
    4147<< CHATMESSAGE 188 FROM_HANDLE bob
  • protocols/skype/t/groupchat-topic-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
     
    55<< PRIVMSG &bitlbee :account add skype alice foo
    66<< PRIVMSG &bitlbee :account skype on
    7 >> JOIN :##cecil/$bob;4d8cc996579
    8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root
    9 << TOPIC ##cecil/$bob;4d8cc996579 :topic
    10 >> TOPIC ##cecil/$bob;4d8cc996579 :topic
     7>> JOIN :##cecil/$bob;4d8cc9965791
     8>> 353 alice = ##cecil/$bob;4d8cc9965791 :@alice bob cecil @root
     9<< TOPIC ##cecil/$bob;4d8cc9965791 :topic
     10>> TOPIC ##cecil/$bob;4d8cc9965791 :topic
  • protocols/skype/t/info-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/login-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/msg-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/skype/t/set-mood-text-bitlbee.mock

    r3fbce97 r63cad66  
    1 >> NOTICE *
     1>> NOTICE AUTH
    22<< NICK alice
    33<< USER alice alice localhost :Alice
  • protocols/twitter/twitter.c

    r3fbce97 r63cad66  
    678678        ic->flags &= ~OPT_LOGGED_IN;
    679679
     680        // Remove the main_loop function from the function queue.
     681        b_event_remove(td->main_loop_id);
     682
     683        if (td->timeline_gc) {
     684                imcb_chat_free(td->timeline_gc);
     685        }
     686
    680687        if (td) {
    681                 // Remove the main_loop function from the function queue.
    682                 b_event_remove(td->main_loop_id);
    683 
    684                 if (td->timeline_gc) {
    685                         imcb_chat_free(td->timeline_gc);
    686                 }
    687 
    688688                if (td->filter_update_id > 0) {
    689689                        b_event_remove(td->filter_update_id);
  • protocols/twitter/twitter_http.c

    r3fbce97 r63cad66  
    2424/***************************************************************************\
    2525*                                                                           *
    26 *  Some functions within this file have been copied from other files within  *
     26*  Some funtions within this file have been copied from other files within  *
    2727*  BitlBee.                                                                 *
    2828*                                                                           *
     
    5353        char *tmp;
    5454        GString *request = g_string_new("");
    55         void *ret = NULL;
     55        void *ret;
    5656        char *url_arguments;
    5757        url_t *base_url = NULL;
     
    7272                base_url = g_new0(url_t, 1);
    7373                if (!url_set(base_url, url_string)) {
    74                         goto error;
     74                        g_free(base_url);
     75                        return NULL;
    7576                }
    7677        }
     
    131132        }
    132133
    133 error:
    134134        g_free(url_arguments);
    135135        g_string_free(request, TRUE);
  • protocols/twitter/twitter_lib.c

    r3fbce97 r63cad66  
    314314        td = ic->proto_data;
    315315
     316        txl = g_new0(struct twitter_xml_list, 1);
     317        txl->list = td->follow_ids;
     318
    316319        // Parse the data.
    317320        if (!(parsed = twitter_parse_response(ic, req))) {
    318321                return;
    319322        }
    320 
    321         txl = g_new0(struct twitter_xml_list, 1);
    322         txl->list = td->follow_ids;
    323323
    324324        twitter_xt_get_friends_id_list(parsed, txl);
     
    390390        }
    391391
     392        txl = g_new0(struct twitter_xml_list, 1);
     393        txl->list = NULL;
     394
    392395        // Get the user list from the parsed xml feed.
    393396        if (!(parsed = twitter_parse_response(ic, req))) {
    394397                return;
    395398        }
    396 
    397         txl = g_new0(struct twitter_xml_list, 1);
    398         txl->list = NULL;
    399 
    400399        twitter_xt_get_users(parsed, txl);
    401400        json_value_free(parsed);
     
    13901389        td = ic->proto_data;
    13911390
     1391        txl = g_new0(struct twitter_xml_list, 1);
     1392        txl->list = NULL;
     1393
    13921394        // The root <statuses> node should hold the list of statuses <status>
    13931395        if (!(parsed = twitter_parse_response(ic, req))) {
    13941396                goto end;
    13951397        }
    1396 
    1397         txl = g_new0(struct twitter_xml_list, 1);
    1398         txl->list = NULL;
    1399 
    14001398        twitter_xt_get_status_list(ic, parsed, txl);
    14011399        json_value_free(parsed);
     
    14301428        td = ic->proto_data;
    14311429
     1430        txl = g_new0(struct twitter_xml_list, 1);
     1431        txl->list = NULL;
     1432
    14321433        // The root <statuses> node should hold the list of statuses <status>
    14331434        if (!(parsed = twitter_parse_response(ic, req))) {
    14341435                goto end;
    14351436        }
    1436 
    1437         txl = g_new0(struct twitter_xml_list, 1);
    1438         txl->list = NULL;
    1439 
    14401437        twitter_xt_get_status_list(ic, parsed, txl);
    14411438        json_value_free(parsed);
  • protocols/yahoo/libyahoo2.c

    r3fbce97 r63cad66  
    1212 * GNU GPL.
    1313 *
    14  * This code is derivative of Gaim <http://gaim.sourceforge.net>
     14 * This code is derivitive of Gaim <http://gaim.sourceforge.net>
    1515 * copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
    1616 *             1998-1999, Adam Fritzler <afritz@marko.net>
     
    14021402
    14031403        /*
    1404          * Status updates may be spread across multiple packets and not
     1404         * Status updates may be spread accross multiple packets and not
    14051405         * even on buddy boundaries, so keeping some state is important.
    14061406         * So, continue where we left off, and only add a user entry to
  • protocols/yahoo/yahoo.c

    r3fbce97 r63cad66  
    440440{
    441441        struct byahoo_connect_callback_data *d = data;
    442         struct im_connection *ic;
    443 
    444         if (!(ic = byahoo_get_ic_by_id(d->id))) {
    445                 g_free(d);
    446                 return;
    447         }
    448 
    449         if (source == -1) {
    450                 d->callback(NULL, 0, d->data);
    451                 imcb_error(ic, "Could not connect to server");
    452                 imc_logout(ic, TRUE);
     442
     443        if (!byahoo_get_ic_by_id(d->id)) {
    453444                g_free(d);
    454445                return;
  • protocols/yahoo/yahoo2_callbacks.h

    r3fbce97 r63cad66  
    685685 * Name: ext_yahoo_connect_async
    686686 *      Connect to a host:port asynchronously. This function should return
    687  *      immediately returning a tag used to identify the connection handler,
     687 *      immediately returing a tag used to identify the connection handler,
    688688 *      or a pre-connect error (eg: host name lookup failure).
    689689 *      Once the connect completes (successfully or unsuccessfully), callback
  • root_commands.c

    r3fbce97 r63cad66  
    163163                irc_umode_set(irc, "+R", 1);
    164164
    165                 if (irc->caps & CAP_SASL) {
    166                         irc_user_t *iu = irc->user;
    167                         irc_send_num(irc, 900, "%s!%s@%s %s :You are now logged in as %s",
    168                                 iu->nick, iu->user, iu->host, iu->nick, iu->nick);
    169                 }
    170 
    171165                bitlbee_whatsnew(irc);
    172166
     
    244238                irc->status |= USTATUS_IDENTIFIED;
    245239                irc_umode_set(irc, "+R", 1);
    246 
    247                 if (irc->caps & CAP_SASL) {
    248                         irc_user_t *iu = irc->user;
    249                         irc_send_num(irc, 900, "%s!%s@%s %s :You are now logged in as %s",
    250                                 iu->nick, iu->user, iu->host, iu->nick, iu->nick);
    251                 }
    252240
    253241                /* Set this var now, or anyone who logs in to his/her
     
    425413
    426414                if (prpl == NULL) {
    427                         if (is_protocol_disabled(cmd[2])) {
    428                                 irc_rootmsg(irc, "Protocol disabled in global config");
    429                         } else {
    430                                 irc_rootmsg(irc, "Unknown protocol");
    431                         }
     415                        irc_rootmsg(irc, "Unknown protocol");
    432416                        return;
    433417                }
  • tests/Makefile

    r3fbce97 r63cad66  
    1515distclean: clean
    1616
    17 main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o
     17main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o
    1818
    1919test_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_set.o check_jabber_sasl.o check_jabber_util.o
  • tests/check.c

    r3fbce97 r63cad66  
    4242        gettimeofday(time, 0);
    4343        return((double) time->tv_sec + (double) time->tv_usec / 1000000);
    44 }
    45 
    46 void sighandler_shutdown_setup()
    47 {
    48         /* no-op. originally defined in unix.c, needed by bitlbee.c */
    4944}
    5045
  • tests/check_jabber_util.c

    r3fbce97 r63cad66  
    3737        fail_unless(jabber_buddy_by_jid(ic, "wilmer@GAAST.NET/BitlBee", GET_BUDDY_CREAT) == budw1);
    3838
    39         fail_unless(jabber_buddy_by_jid(ic, "wilmer@gaast.net", GET_BUDDY_EXACT));
     39        fail_if(jabber_buddy_by_jid(ic, "wilmer@gaast.net", GET_BUDDY_EXACT));
    4040        fail_unless(jabber_buddy_by_jid(ic, "WILMER@gaast.net", 0) == budw3);
    4141
     
    105105}
    106106
    107 static void check_hipchat_slug(int l)
    108 {
    109         int i;
    110 
    111         const char *tests[] = {
    112                 "test !\"#$%&\'()*+,-./0123456789:;<=>?@ABC", "test_!#$%\()*+,-.0123456789;=?abc",
    113                 "test XYZ[\\]^_`abc", "test_xyz[\\]^_`abc",
    114                 "test {|}~¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ", "test_{|}~¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿àáâãäåæ",
    115                 "test IJ ij I ı I ı", "test_ij_ij_i_ı_i_ı",
    116                 NULL,
    117         };
    118 
    119         for (i = 0; tests[i]; i += 2) {
    120                 char *new = hipchat_make_channel_slug(tests[i]);
    121                 fail_unless(!strcmp(tests[i + 1], new));
    122                 g_free(new);
    123         }
    124 }
    125 
    126107Suite *jabber_util_suite(void)
    127108{
     
    140121        tcase_add_test(tc_core, check_buddy_add);
    141122        tcase_add_test(tc_core, check_compareJID);
    142         tcase_add_test(tc_core, check_hipchat_slug);
    143123        return s;
    144124}
  • tests/check_user.c

    r3fbce97 r63cad66  
    4646END_TEST
    4747
    48 START_TEST(test_user_del_nonexistent)
     48START_TEST(test_user_del_nonexistant)
    4949irc_t * irc = torture_irc();
    5050fail_unless(user_del(irc, "foo") == 0);
     
    7171        tcase_add_test(tc_core, test_user_add_exists);
    7272        tcase_add_test(tc_core, test_user_del_invalid);
    73         tcase_add_test(tc_core, test_user_del_nonexistent);
     73        tcase_add_test(tc_core, test_user_del_nonexistant);
    7474        tcase_add_test(tc_core, test_user_del);
    7575        tcase_add_test(tc_core, test_user_rename);
  • unix.c

    r3fbce97 r63cad66  
    4848global_t global;        /* Against global namespace pollution */
    4949
    50 static struct {
    51         int fd[2];
    52         int tag;
    53 } shutdown_pipe = {{-1 , -1}, 0};
    54 
     50static int signal_shutdown_pipe[2] = { -1, -1 };
    5551static void sighandler_shutdown(int signal);
    5652static void sighandler_crash(int signal);
     
    160156        sigaction(SIGSEGV, &sig, &old);
    161157
    162         sighandler_shutdown_setup();
    163 
    164         sig.sa_handler = sighandler_shutdown;
    165         sigaction(SIGINT, &sig, &old);
    166         sigaction(SIGTERM, &sig, &old);
     158        /* Use a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */
     159        if (pipe(signal_shutdown_pipe) == 0) {
     160                b_input_add(signal_shutdown_pipe[0], B_EV_IO_READ, bitlbee_shutdown, NULL);
     161                sig.sa_handler = sighandler_shutdown;
     162                sigaction(SIGINT, &sig, &old);
     163                sigaction(SIGTERM, &sig, &old);
     164        }
    167165
    168166        if (!getuid() || !geteuid()) {
     
    258256}
    259257
    260 /* Set up a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */
    261 void sighandler_shutdown_setup()
    262 {
    263         if (shutdown_pipe.fd[0] != -1) {
    264                 /* called again from a forked process, clean up to avoid propagating the signal */
    265                 b_event_remove(shutdown_pipe.tag);
    266                 close(shutdown_pipe.fd[0]);
    267                 close(shutdown_pipe.fd[1]);
    268         }
    269 
    270         if (pipe(shutdown_pipe.fd) == 0) {
    271                 shutdown_pipe.tag = b_input_add(shutdown_pipe.fd[0], B_EV_IO_READ, bitlbee_shutdown, NULL);
    272         }
    273 }
    274 
    275258/* Signal handler for SIGTERM and SIGINT */
    276259static void sighandler_shutdown(int signal)
     
    278261        /* Write a single null byte to the pipe, just to send a message to the main loop.
    279262         * This gets handled by bitlbee_shutdown (the b_input_add callback for this pipe) */
    280         write(shutdown_pipe.fd[1], "", 1);
     263        write(signal_shutdown_pipe[1], "", 1);
    281264}
    282265
     
    292275        for (l = irc_connection_list; l; l = l->next) {
    293276                irc_t *irc = l->data;
    294                 sock_make_blocking(irc->fd);
    295277                write(irc->fd, message, len);
    296278        }
Note: See TracChangeset for help on using the changeset viewer.