Changes in / [3fbce97:63cad66]
- Files:
-
- 2 deleted
- 117 edited
Legend:
- Unmodified
- Added
- Removed
-
.travis.yml
r3fbce97 r63cad66 1 sudo: false2 1 language: c 3 2 … … 5 4 - ./configure 6 5 - make check 7 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d6 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us 8 7 9 # ubuntu precise doesn't have libotr5, so extract a prebuilt version to ~/otr10 8 before_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 16 13 17 14 env: 18 15 global: 19 - PKG_CONFIG_PATH=$HOME/otr/usr/lib/pkgconfig/20 - LD_LIBRARY_PATH=$HOME/otr/usr/lib/21 16 # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created 22 17 # via the "travis encrypt" command using the project repo's public key … … 24 19 25 20 addons: 26 apt:27 packages:28 - libevent-dev29 - libpurple-dev30 - check31 21 coverity_scan: 32 22 project: -
Makefile
r3fbce97 r63cad66 10 10 11 11 # Program variables 12 objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_c ap.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.o12 objects = 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 13 13 headers = $(wildcard $(_SRCDIR_)*.h $(_SRCDIR_)lib/*.h $(_SRCDIR_)protocols/*.h) 14 14 subdirs = lib protocols … … 30 30 31 31 install: install-bin install-doc install-plugins 32 @echo33 @echo Installed successfully34 @echo35 32 @if ! [ -d $(DESTDIR)$(CONFIG) ]; then echo -e '\nThe configuration directory $(DESTDIR)$(CONFIG) does not exist yet, don'\''t forget to create it!'; fi 36 33 @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 … … 38 35 @echo If you want to start BitlBee using systemd, try \"make install-systemd\". 39 36 endif 40 @echo To be able to compile third party plugins, run \"make install-dev\"41 37 @echo 42 38 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 \ 45 41 all clean distclean tar $(subdirs) doc 46 42 -
README.md
r3fbce97 r63cad66 16 16 License: GPLv2 17 17 18 ## Installation18 ## Development 19 19 20 BitlBee is available in the package managers of most distros.20 Use github pull requests against the 'develop' branch to submit patches. 21 21 22 For debian/ubuntu/etc you may use the nightly APT repository: http://code.bitlbee.org/debian/ 22 The '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. 23 23 24 You can also use a public server (such as `im.bitlbee.org`) instead of installing it: http://bitlbee.org/main.php/servers.html 24 Building: 25 25 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 27 30 28 If you wish to compile it yourself, ensure you have the following packages and their headers: 31 # Also try --asan=1 for AddressSanitizer 29 32 30 * glib 2.16 or newer (not to be confused with glibc) 31 * gnutls 32 * python 2 or 3 (for the user guide) 33 make 33 34 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. 35 BITLBEE_DEBUG=1 ./bitlbee -Dnv 36 ``` 36 37 37 Once you have the dependencies, building should be a matter of: 38 See ./doc/README and ./doc/HACKING for more details. 38 39 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` 40 Mappings of bzr revisions to git commits (for historical purposes) are available in ./doc/git-bzr-rev-map 51 41 52 42 ## Help? 53 43 54 Join **#BitlBee** on OFTC (**irc.oftc.net**) (OFTC, *not* FreeNode!) 44 Join **#BitlBee** on OFTC (**irc.oftc.net**) (OFTC, *not* FreeNode!) and flame us right in the face. :-) -
bitlbee.c
r3fbce97 r63cad66 311 311 b_event_remove(global.listen_watch_source_id); 312 312 313 /* Make a new pipe for the shutdown signal handler */314 sighandler_shutdown_setup();315 316 313 /* Make the connection. */ 317 314 irc = irc_new(new_socket); -
bitlbee.h
r3fbce97 r63cad66 158 158 } global_t; 159 159 160 void sighandler_shutdown_setup(void);161 162 160 int bitlbee_daemon_init(void); 163 161 int bitlbee_inetd_init(void); -
conf.c
r3fbce97 r63cad66 37 37 38 38 static int conf_loadini(conf_t *conf, char *file); 39 static void conf_free(conf_t *conf);40 39 41 40 conf_t *conf_load(int argc, char *argv[]) … … 74 73 if (i == 0) { 75 74 fprintf(stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file); 76 conf_free(conf);77 75 return NULL; 78 76 } else if (i == -1) { … … 106 104 g_free(global.conf_file); 107 105 global.conf_file = g_strdup(optarg); 108 conf_free(conf);106 g_free(conf); 109 107 /* Re-evaluate arguments. Don't use this option twice, 110 108 you'll end up in an infinite loop! Hope this trick … … 137 135 " -h Show this help page.\n" 138 136 " -V Show version info.\n"); 139 conf_free(conf);140 137 return NULL; 141 138 } 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); 145 141 return NULL; 146 142 } else if (opt == 'u') { … … 166 162 they're secure when in fact they're not. */ 167 163 fprintf(stderr, "Error: Could not read CA file %s: %s\n", conf->cafile, strerror(errno)); 168 conf_free(conf);169 164 return NULL; 170 165 } 171 166 172 167 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, and181 3. to distribute modified versions182 */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 201 168 } 202 169 … … 252 219 g_free(conf->configdir); 253 220 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);257 221 } else if (g_strcasecmp(ini->key, "motdfile") == 0) { 258 222 g_free(conf->motdfile); … … 295 259 } else if (url->proto == PROTO_SOCKS5) { 296 260 proxytype = PROXY_SOCKS5; 297 } else if (url->proto == PROTO_SOCKS4A) {298 proxytype = PROXY_SOCKS4A;299 261 } 300 262 -
configure
r3fbce97 r63cad66 24 24 pcdir='$prefix/lib/pkgconfig' 25 25 systemlibdirs="/lib64 /usr/lib64 /usr/local/lib64 /lib /usr/lib /usr/local/lib" 26 sysroot=''27 28 configure_args="$@"29 26 30 27 # Set these to default-on to let it be overriden by either the user or purple … … 56 53 pie=1 57 54 58 arch= $(uname -s)59 cpu= $(uname -m)55 arch=`uname -s` 56 cpu=`uname -m` 60 57 61 58 GLIB_MIN_VERSION=2.16 … … 108 105 109 106 while [ -n "$1" ]; do 110 e=" $(expr "X$1" : 'X--\(.*=.*\)')"107 e="`expr "X$1" : 'X--\(.*=.*\)'`" 111 108 if [ -z "$e" ]; then 112 109 cat<<EOF … … 156 153 157 154 --target=... Cross compilation target same as host 158 --sysroot=... Cross compilation sysroot $sysroot159 155 EOF 160 156 exit; … … 165 161 166 162 # 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')163 bindir=`eval echo "$bindir/" | sed 's/\/\{1,\}/\//g'` 164 sbindir=`eval echo "$sbindir/" | sed 's/\/\{1,\}/\//g'` 165 etcdir=`eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g'` 166 mandir=`eval echo "$mandir/" | sed 's/\/\{1,\}/\//g'` 167 datadir=`eval echo "$datadir/" | sed 's/\/\{1,\}/\//g'` 168 config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'` 169 plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'` 174 170 rpcplugindir=$(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')171 includedir=`eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g'` 172 libevent=`eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g'` 173 174 pidfile=`eval echo "$pidfile" | sed 's/\/\{1,\}/\//g'` 175 ipcsocket=`eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g'` 176 pcdir=`eval echo "$pcdir" | sed 's/\/\{1,\}/\//g'` 181 177 182 178 protocols_mods="" … … 184 180 cat <<EOF >Makefile.settings 185 181 ## BitlBee settings, generated by configure 186 187 # ./configure $configure_args188 189 182 PREFIX=$prefix 190 183 BINDIR=$bindir … … 240 233 of them can/will be overridden at run-time */ 241 234 242 #define BITLBEE_CONFIGURE_ARGS "$configure_args"243 244 235 #define CONFIG "$config" 245 236 #define ETCDIR "$etcdir" … … 256 247 257 248 if [ -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 282 252 CC=$target-cc 283 253 LD=$target-ld 284 STRIP=$target-strip254 systemlibdirs="/usr/$target/lib" 285 255 fi 286 256 … … 351 321 if $PKG_CONFIG glib-2.0 --atleast-version=$GLIB_MIN_VERSION; then 352 322 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)323 EFLAGS+=`$PKG_CONFIG --libs glib-2.0 gmodule-2.0` 324 CFLAGS+=`$PKG_CONFIG --cflags glib-2.0 gmodule-2.0` 355 325 EOF 356 326 else 357 327 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.' 359 329 exit 1 360 330 fi … … 392 362 if $PKG_CONFIG --exists gnutls; then 393 363 cat <<EOF >>Makefile.settings 394 EFLAGS+= $($PKG_CONFIG --libs gnutls) $(libgcrypt-config --libs)395 CFLAGS+= $($PKG_CONFIG --cflags gnutls) $(libgcrypt-config --cflags)364 EFLAGS+=`$PKG_CONFIG --libs gnutls` `libgcrypt-config --libs` 365 CFLAGS+=`$PKG_CONFIG --cflags gnutls` `libgcrypt-config --cflags` 396 366 EOF 397 367 ssl=gnutls 398 if ! $PKG_CONFIGgnutls --atleast-version=2.8; then368 if ! pkg-config gnutls --atleast-version=2.8; then 399 369 echo 400 370 echo 'Warning: With GnuTLS versions <2.8, certificate expire dates are not verified.' … … 403 373 elif libgnutls-config --version > /dev/null 2> /dev/null; then 404 374 cat <<EOF >>Makefile.settings 405 EFLAGS+= $(libgnutls-config --libs) $(libgcrypt-config --libs)406 CFLAGS+= $(libgnutls-config --cflags) $(libgcrypt-config --cflags)375 EFLAGS+=`libgnutls-config --libs` `libgcrypt-config --libs` 376 CFLAGS+=`libgnutls-config --cflags` `libgcrypt-config --cflags` 407 377 EOF 408 378 … … 418 388 if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG nss; then 419 389 cat<<EOF >>Makefile.settings 420 EFLAGS+= $($PKG_CONFIG --libs nss)421 CFLAGS+= $($PKG_CONFIG --cflags nss)390 EFLAGS+=`$PKG_CONFIG --libs nss` 391 CFLAGS+=`$PKG_CONFIG --cflags nss` 422 392 EOF 423 393 … … 664 634 if [ -z "$systemdsystemunitdir" ]; then 665 635 if $PKG_CONFIG --exists systemd; then 666 systemdsystemunitdir= $($PKG_CONFIG --variable=systemdsystemunitdir systemd)636 systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd` 667 637 fi 668 638 fi … … 692 662 693 663 otrprefix="" 664 for i in / /usr /usr/local; do 665 if [ -f ${i}/lib/libotr.a ]; then 666 otrprefix=${i} 667 break 668 fi 669 done 694 670 if [ "$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 676 fi 703 677 if [ "$otr" = 1 ]; then 704 678 # BI == built-in 705 679 echo '#define OTR_BI' >> config.h 706 echo "EFLAGS+= $($PKG_CONFIG --libs libotr) $(libgcrypt-config --libs)" >> Makefile.settings707 echo "CFLAGS+= $($PKG_CONFIG --cflags libotr) $(libgcrypt-config --cflags)" >> Makefile.settings680 echo "EFLAGS+=-L${otrprefix}/lib -lotr -lgcrypt" >> Makefile.settings 681 echo "CFLAGS+=-I${otrprefix}/include" >> Makefile.settings 708 682 echo 'OTR_BI=otr.o' >> Makefile.settings 709 683 elif [ "$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.712 684 echo '#define OTR_PI' >> config.h 713 echo "OTRFLAGS= $($PKG_CONFIG --libs libotr) $(libgcrypt-config --libs)" >> Makefile.settings714 echo "CFLAGS+= $($PKG_CONFIG --cflags libotr) $(libgcrypt-config --cflags)" >> Makefile.settings685 echo "OTRFLAGS=-L${otrprefix}/lib -lotr" >> Makefile.settings 686 echo "CFLAGS+=-I${otrprefix}/include" >> Makefile.settings 715 687 echo 'OTR_PI=otr.so' >> Makefile.settings 688 fi 689 if [ "$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... 716 694 fi 717 695 -
dcc.c
r3fbce97 r63cad66 265 265 } 266 266 267 /* How likely is it that a 32-bit integer gets split ac ross267 /* How likely is it that a 32-bit integer gets split accross 268 268 packet boundaries? Chances are rarely 0 so let's be sure. */ 269 269 if ((df->acked_len = (df->acked_len + ret) % 4) > 0) { -
debian/changelog
r3fbce97 r63cad66 1 bitlbee (3. 4.1-1) unstable; urgency=medium1 bitlbee (3.2.2-2) UNRELEASED; urgency=medium 2 2 3 3 * 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 8 6 9 7 bitlbee (3.2.2-1) unstable; urgency=medium -
debian/source/options
r3fbce97 r63cad66 1 --diff-ignore='(^|/)\. git'1 --diff-ignore='(^|/)\.bzr' -
doc/CHANGES
r3fbce97 r63cad66 429 429 officially be treated as case sensitive. 430 430 - Fully stripping spaces from AIM screennames, this didn't happen completely 431 which sever ely breaks the IRC protocol.431 which severly breaks the IRC protocol. 432 432 - Removed all the yellow tape around daemon mode, it's pretty mature by now: 433 433 testing.bitlbee.org serves all (~30) SSL users from one daemon mode … … 629 629 some situations. 630 630 - Outgoing MSN typing notifications are now understood correctly by the 631 orig inal MS Mac/Windows clients (again).631 orignal MS Mac/Windows clients (again). 632 632 - Added "account add $protocol" to the documentation, got rid of a lot 633 633 of over-markup (i.e. overuse of bold-tags), reviewed some other parts. -
doc/HACKING
r3fbce97 r63cad66 14 14 calls and arguments where that seemed useful, etc. 15 15 16 However, up to late in the 1.2 series, the IRC core was still spread ac ross16 However, up to late in the 1.2 series, the IRC core was still spread accross 17 17 several files, mostly irc.c + irc_commands.c and pieces and bits in 18 18 nogaim.c. If you're looking for a textbook example of layer violation, start -
doc/README
r3fbce97 r63cad66 8 8 to set up the build system. If configure succeeds, run make to build BitlBee. 9 9 make install will move all the files to the right places. 10 11 RUN MODES12 =========13 10 14 11 --- (Fork)Daemon mode … … 92 89 ================== 93 90 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) 91 Cygwin NOTE: You'll need a glib installation to run BitlBee. However, Cygwin 92 doesn'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 94 fine. You'll probably like bitlbeed or xinetd to get it running on the 95 network. 96 97 On some non-Linux systems the program still suffers from some random bugs. 98 Please do report them, we might be able to fix them if they're not too 99 mysterious. 100 101 Also, the configure script is known to not work very well with non-Bash 102 shells, so if you experience problems, make sure you use bash to run the 103 script. Same for the Makefile, it only works well with GNU make. (gmake on 104 most BSD systems) 98 105 99 106 If someone can tell us how to write Makefiles that work with both/all … … 146 153 ============================= 147 154 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. 155 There used to be a note here about the simple obfuscation method used to 156 make the passwords in the configuration files unreadable. However, BitlBee 157 now uses a better format (and real encryption (salted MD5 and RC4)) to store 158 the passwords. This means that people who somehow get their hands on your 159 configuration files can't easily extract your passwords from them anymore. 151 160 152 161 However, once you log into the BitlBee server and send your password, an 153 162 intruder 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. 163 avoided, of course. The new format is a lot more reliable (because it can't 164 be cracked with just very basic crypto analysis anymore), but you still have 165 to be careful. The main extra protection offered by the new format is that 166 the files can only be cracked with some help from the user (by sending the 167 password at login time). 168 169 So if you run a public server, it's most important that you don't give root 170 access to people who like to play with tcpdump. Also, it's a good idea to 171 delete all *.nicks/*.accounts files as soon as BitlBee converted them to the 172 new format (which happens as soon as the user logs in, it can't be done 173 automatically because it needs the password for that account). You won't 174 need them anymore (unless you want to switch back to an older BitlBee 175 version) and they only make it easier for others to crack your passwords. 176 156 177 157 178 LEGAL … … 160 181 BitlBee is distributed under the GPL (GNU General Public License). See the 161 182 file COPYING for this license. 183 184 The MD5 algorithm code is licensed under the Aladdin license. This license 185 can be found in the files, to which this applies. The SHA1 algorithm code 186 is licensed under the Mozilla Public License, see http://www.mozilla.org/MPL/ 187 for details. 162 188 163 189 The Yahoo! library used by BitlBee is libyahoo2 <http://libyahoo2.sf.net/>, -
doc/user-guide/Installation.xml
r3fbce97 r63cad66 73 73 <para> 74 74 By default, BitlBee runs as the user nobody. You might want 75 to run it as a sep arate user (some computers run named or apache as nobody).75 to run it as a seperate user (some computers run named or apache as nobody). 76 76 </para> 77 77 -
doc/user-guide/commands.xml
r3fbce97 r63cad66 182 182 183 183 <para> 184 For more info rmation about a setting, see <emphasis>help set <setting></emphasis>.184 For more infomation about a setting, see <emphasis>help set <setting></emphasis>. 185 185 </para> 186 186 … … 240 240 241 241 <para> 242 For more info rmation about a setting, see <emphasis>help set <setting></emphasis>.242 For more infomation about a setting, see <emphasis>help set <setting></emphasis>. 243 243 </para> 244 244 … … 785 785 <para> 786 786 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.803 787 </para> 804 788 </description> … … 1109 1093 1110 1094 <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. 1112 1096 </para> 1113 1097 … … 1174 1158 <description> 1175 1159 <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. 1177 1161 </para> 1178 1162 … … 1188 1172 <description> 1189 1173 <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. 1191 1175 </para> 1192 1176 … … 1340 1324 </bitlbee-setting> 1341 1325 1342 <bitlbee-setting name="proxy" type="string" scope="account">1343 <default><local><auto></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><local></emphasis> (to try a direct connection first) and <emphasis><auto></emphasis> (to try to discover a proxy). For example, "<local>;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 1362 1326 <bitlbee-setting name="query_order" type="string" scope="global"> 1363 1327 <default>lifo</default> … … 1420 1384 </bitlbee-setting> 1421 1385 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 1453 1386 <bitlbee-setting name="server" type="string" scope="account"> 1454 1387 <description> … … 1484 1417 1485 1418 <bitlbee-setting name="show_users" type="string" scope="channel"> 1486 <default>online+, special%,away</default>1419 <default>online+,away</default> 1487 1420 1488 1421 <description> … … 1491 1424 and any modes they should have. The following statuses are currently 1492 1425 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>. 1495 1427 </para> 1496 1428 … … 1498 1430 If a status is followed by a valid channel mode character 1499 1431 (@, % or +), it will be given to users with that status. 1500 For example, <emphasis>online@, special%,away+,offline</emphasis>1501 willshow all users in the channel. Online people will1432 For example, <emphasis>online@,away+,offline</emphasis> will 1433 show all users in the channel. Online people will 1502 1434 have +o, people who are online but away will have +v, 1503 1435 and others will have no special modes. … … 1959 1891 1960 1892 <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 nec essary. 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> 1962 1894 </description> 1963 1895 -
doc/user-guide/misc.xml
r3fbce97 r63cad66 90 90 91 91 <para> 92 Away states have different names ac ross different protocols. BitlBee will try to pick the best available option for every connection:92 Away states have different names accross different protocols. BitlBee will try to pick the best available option for every connection: 93 93 </para> 94 94 … … 146 146 147 147 <para> 148 Control channels are where you see your contacts. By default, you will have one control channel called &bitlbee, containing all your contacts. But you can create more, if you want, and divide your contact list ac ross several channels.148 Control channels are where you see your contacts. By default, you will have one control channel called &bitlbee, containing all your contacts. But you can create more, if you want, and divide your contact list accross several channels. 149 149 </para> 150 150 -
doc/user-guide/quickstart.xml
r3fbce97 r63cad66 11 11 12 12 <para> 13 You need toregister 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 <password></emphasis> (without the brackets!).13 You 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 <password></emphasis> (without the brackets!). 14 14 </para> 15 15 -
help.c
r3fbce97 r63cad66 105 105 h = *help; 106 106 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) { 110 108 close(h->fd); 111 109 last_fd = h->fd; … … 148 146 if (lseek(h->fd, h->offset.file_offset, SEEK_SET) == -1 || 149 147 read(h->fd, s, h->length) != h->length) { 150 g_free(s);151 148 return NULL; 152 149 } -
ipc.c
r3fbce97 r63cad66 590 590 } 591 591 592 memcpy(recv_fd, CMSG_DATA(cmsg), sizeof(int));592 *recv_fd = *(int *) CMSG_DATA(cmsg); 593 593 /* 594 594 fprintf( stderr, "pid %d received fd %d\n", (int) getpid(), *recv_fd ); … … 758 758 cmsg->cmsg_type = SCM_RIGHTS; 759 759 cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd)); 760 memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(int));760 *(int *) CMSG_DATA(cmsg) = send_fd; 761 761 msg.msg_controllen = cmsg->cmsg_len; 762 762 #endif -
irc.c
r3fbce97 r63cad66 129 129 s = set_add(&b->set, "show_offline", "false", set_eval_bw_compat, irc); 130 130 s->flags |= SET_HIDDEN; 131 s = set_add(&b->set, "self_messages", "true", set_eval_self_messages, irc);132 131 s = set_add(&b->set, "simulate_netsplit", "true", set_eval_bool, irc); 133 132 s = set_add(&b->set, "timezone", "local", set_eval_timezone, irc); … … 154 153 set_eval_charset(set_find(&b->set, "charset"), set_getstr(&b->set, "charset")); 155 154 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"); 157 156 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, 159 158 "If you read this, you most likely accidentally " 160 159 "started BitlBee in inetd mode on the command line. " … … 381 380 conv = NULL; 382 381 } else { 383 irc_write(irc, ":%s NOTICE *:%s", irc->root->host,382 irc_write(irc, ":%s NOTICE AUTH :%s", irc->root->host, 384 383 "Warning: invalid characters received at login time."); 385 384 … … 728 727 int irc_check_login(irc_t *irc) 729 728 { 730 if (irc->user->user && irc->user->nick && !(irc->status & USTATUS_CAP_PENDING)) {729 if (irc->user->user && irc->user->nick) { 731 730 if (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED)) { 732 731 irc_send_num(irc, 464, ":This server is password-protected."); -
irc.h
r3fbce97 r63cad66 49 49 USTATUS_SHUTDOWN = 8, /* Now used to indicate we're shutting down. 50 50 Currently just blocks irc_vawrite(). */ 51 USTATUS_CAP_PENDING = 16,52 USTATUS_SASL_PLAIN_PENDING = 32,53 51 54 52 /* Not really status stuff, but other kinds of flags: For slightly … … 67 65 } irc_status_t; 68 66 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 77 67 struct irc_user; 78 68 … … 112 102 113 103 struct bee *b; 114 guint32 caps;115 104 } irc_t; 116 105 … … 313 302 gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name); 314 303 void irc_channel_update_ops(irc_channel_t *ic, char *value); 315 char irc_channel_user_get_prefix(irc_channel_user_t *icu);316 304 char *set_eval_irc_channel_ops(struct set *set, char *value); 317 305 gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu); … … 343 331 irc_channel_user_flags_t old_flags, irc_channel_user_flags_t new_flags); 344 332 void 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);347 333 348 334 /* irc_user.c */ … … 358 344 char *set_eval_timezone(struct set *set, char *value); 359 345 char *irc_format_timestamp(irc_t *irc, time_t msg_ts); 360 char *set_eval_self_messages(struct set *set, char *value);361 346 362 347 /* irc_im.c */ … … 364 349 void bee_irc_user_nick_reset(irc_user_t *iu); 365 350 366 /* irc_cap.c */367 void irc_cmd_cap(irc_t *irc, char **cmd);368 369 351 #endif -
irc_channel.c
r3fbce97 r63cad66 213 213 } 214 214 215 /* Skip the free/init if nothing is being changed */216 if (ic->f == new) {217 return value;218 }219 220 215 /* TODO: Return values. */ 221 216 if (ic->f && ic->f->_free) { … … 260 255 261 256 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 }266 257 return 0; 267 258 } … … 436 427 changes); 437 428 } 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;450 429 } 451 430 … … 614 593 615 594 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 626 595 if (bytes_written > MAX_NICK_LENGTH) { 627 596 translit_name[MAX_NICK_LENGTH] = '\0'; -
irc_commands.c
r3fbce97 r63cad66 28 28 #include "help.h" 29 29 #include "ipc.h" 30 #include "base64.h"31 30 32 31 static void irc_cmd_pass(irc_t *irc, char **cmd) … … 56 55 irc_setpass(irc, cmd[1]); 57 56 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 numerics98 * 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 case139 * 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;172 57 } 173 58 } … … 198 83 irc->status &= ~USTATUS_IDENTIFIED; 199 84 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 206 85 irc_rootmsg(irc, "Changing nicks resets your identify status. " 207 86 "Re-identify or register a new account if you want " … … 806 685 807 686 static const command_t irc_commands[] = { 808 { "cap", 1, irc_cmd_cap, 0 },809 687 { "pass", 1, irc_cmd_pass, 0 }, 810 688 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, … … 843 721 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 844 722 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 845 { "authenticate", 1, irc_cmd_authenticate, 0 },846 723 { NULL } 847 724 }; -
irc_im.c
r3fbce97 r63cad66 84 84 } 85 85 86 /* Sanitize */87 str_reject_chars(iu->user, " ", '_');88 str_reject_chars(iu->host, " ", '_');86 while ((s = strchr(iu->user, ' '))) { 87 *s = '_'; 88 } 89 89 90 90 if (bu->flags & BEE_USER_LOCAL) { … … 118 118 if (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) { 119 119 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);126 120 } 127 121 … … 207 201 } 208 202 209 static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, guint32 flags,time_t sent_at)203 static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at) 210 204 { 211 205 irc_t *irc = bee->ui_data; 212 206 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;215 207 const char *dst; 216 208 char *prefix = NULL; 217 209 char *wrapped, *ts = NULL; 218 210 char *msg = g_strdup(msg_); 219 char *message_type = "PRIVMSG";220 211 GSList *l; 221 212 … … 225 216 226 217 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 ? : ""); 265 221 } else { 266 222 prefix = ts; … … 293 249 294 250 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); 296 252 g_free(wrapped); 297 253 … … 304 260 } 305 261 306 static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, guint32flags)262 static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, uint32_t flags) 307 263 { 308 264 irc_t *irc = (irc_t *) bee->ui_data; … … 661 617 } 662 618 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)619 static gboolean bee_irc_chat_msg(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at) 664 620 { 665 621 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; 667 623 irc_channel_t *ic = c->ui_data; 668 624 char *wrapped, *ts = NULL; … … 698 654 } 699 655 700 static gboolean bee_irc_chat_remove_user(bee_t *bee, struct groupchat *c, bee_user_t *bu , const char *reason)656 static gboolean bee_irc_chat_remove_user(bee_t *bee, struct groupchat *c, bee_user_t *bu) 701 657 { 702 658 irc_t *irc = bee->ui_data; … … 710 666 using imcb_chat_free() and the channel was IRC_CHANNEL_TEMP, we get into 711 667 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); 713 669 714 670 return TRUE; … … 883 839 acc->prpl->chat_join) { 884 840 char *nick; 885 struct groupchat *gc;886 841 887 842 if (!(nick = set_getstr(&ic->set, "nick"))) { … … 890 845 891 846 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); 893 848 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 }898 849 899 850 return FALSE; … … 912 863 } 913 864 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; 919 867 920 868 return TRUE; … … 1107 1055 df->proto_finished = TRUE; 1108 1056 } 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);1116 1057 } 1117 1058 … … 1144 1085 bee_irc_ft_close, 1145 1086 bee_irc_ft_finished, 1146 1147 bee_irc_log,1148 1087 }; -
irc_send.c
r3fbce97 r63cad66 172 172 irc_t *irc = ic->irc; 173 173 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); 179 175 180 176 if (iu == irc->user) { … … 202 198 } 203 199 204 #define IRC_NAMES_LEN 385205 206 200 void irc_send_names(irc_channel_t *ic) 207 201 { 208 202 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] = ""; 211 204 212 205 /* RFCs say there is no error reply allowed on NAMES, so when the … … 215 208 irc_channel_user_t *icu = l->data; 216 209 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); 243 230 } 244 231 245 232 irc_send_num(ic->irc, 366, "%s :End of /NAMES list", ic->name); 246 247 g_string_free(namelist, TRUE);248 233 } 249 234 … … 264 249 } 265 250 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 292 251 void irc_send_whois(irc_user_t *iu) 293 252 { … … 299 258 if (iu->bu) { 300 259 bee_user_t *bu = iu->bu; 301 char *msg1, *msg2;302 int num;303 260 304 261 irc_send_num(irc, 312, "%s %s.%s :%s network", iu->nick, bu->ic->acc->user, … … 306 263 bu->ic->acc->prpl->name); 307 264 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"); 316 276 } 317 277 … … 334 294 335 295 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; 342 297 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", 354 302 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); 356 305 l = l->next; 357 306 } … … 479 428 iu->nick, iu->user, iu->host, irc->user->nick, ic->name); 480 429 } 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 119 119 } 120 120 } 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 162 162 } 163 163 164 if (req->func != NULL) { 165 req->func(req); 166 } 164 req->func(req); 167 165 http_free(req); 168 166 return FALSE; … … 301 299 } 302 300 303 if (req->func != NULL) { 304 req->func(req); 305 } 301 req->func(req); 306 302 http_free(req); 307 303 return FALSE; … … 416 412 } 417 413 418 if ((req->flags & HTTPC_STREAMING) && req->reply_body && req->func != NULL) {414 if ((req->flags & HTTPC_STREAMING) && req->reply_body) { 419 415 req->func(req); 420 416 } … … 700 696 ssl_disconnect(req->ssl); 701 697 } else { 702 proxy_disconnect(req->fd);698 closesocket(req->fd); 703 699 } 704 700 -
lib/ini.c
r3fbce97 r63cad66 28 28 ini_t *ini_open(char *file) 29 29 { 30 int fd = -1;30 int fd; 31 31 ini_t *ini = NULL; 32 32 struct stat fi; 33 33 34 if ( file &&(fd = open(file, O_RDONLY)) != -1 &&34 if ((fd = open(file, O_RDONLY)) != -1 && 35 35 fstat(fd, &fi) == 0 && 36 36 fi.st_size <= 16384 && -
lib/misc.c
r3fbce97 r63cad66 187 187 } else if (g_strncasecmp(cs + 1, "br", taglen) == 0) { 188 188 *(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';193 189 } 194 190 in++; … … 299 295 300 296 /* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */ 301 /* This fu nction 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! */ 302 298 void http_encode(char *s) 303 299 { … … 771 767 } 772 768 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 150 150 G_MODULE_EXPORT int truncate_utf8(char *string, int maxlen); 151 151 G_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);153 152 154 153 #endif -
lib/proxy.c
r3fbce97 r63cad66 51 51 #endif 52 52 53 static GHashTable *phb_hash = NULL;54 55 53 struct PHB { 56 54 b_event_handler func, proxy_func; … … 63 61 }; 64 62 65 typedef int (*proxy_connect_func)(const char *host, unsigned short port_, struct PHB *phb);66 67 63 static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb); 68 64 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 } 65 static gboolean phb_close(struct PHB *phb) 66 { 67 close(phb->fd); 68 phb->func(phb->data, -1, B_EV_IO_READ); 84 69 g_free(phb->host); 85 70 g_free(phb); … … 104 89 dup2(new_fd, source); 105 90 closesocket(new_fd); 106 phb->fd = source;107 91 phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb); 108 92 return FALSE; … … 117 101 118 102 freeaddrinfo(phb->gai); 119 phb->gai = NULL;120 121 103 b_event_remove(phb->inpa); 122 104 phb->inpa = 0; 123 124 105 if (phb->proxy_func) { 125 106 phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ); 126 107 } else { 127 108 phb->func(phb->data, source, B_EV_IO_READ); 128 phb_free(phb, TRUE);109 g_free(phb); 129 110 } 130 111 … … 190 171 191 172 if (fd < 0 && host) { 192 phb_free(phb, TRUE);173 g_free(phb); 193 174 } 194 175 … … 223 204 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) { 224 205 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); 229 212 } 230 213 … … 241 224 len = sizeof(error); 242 225 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 243 return phb_ free(phb, FALSE);226 return phb_close(phb); 244 227 } 245 228 sock_make_blocking(source); … … 248 231 phb->host, phb->port); 249 232 if (send(source, cmd, strlen(cmd), 0) < 0) { 250 return phb_ free(phb, FALSE);233 return phb_close(phb); 251 234 } 252 235 … … 259 242 g_free(t2); 260 243 if (send(source, cmd, strlen(cmd), 0) < 0) { 261 return phb_ free(phb, FALSE);244 return phb_close(phb); 262 245 } 263 246 } … … 265 248 g_snprintf(cmd, sizeof(cmd), "\r\n"); 266 249 if (send(source, cmd, strlen(cmd), 0) < 0) { 267 return phb_ free(phb, FALSE);250 return phb_close(phb); 268 251 } 269 252 … … 296 279 if (read(source, packet, 9) >= 4 && packet[1] == 90) { 297 280 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); 302 287 } 303 288 … … 309 294 socklen_t len; 310 295 int error = ETIMEDOUT; 311 gboolean is_socks4a = (proxytype == PROXY_SOCKS4A);312 296 313 297 if (phb->inpa > 0) { … … 316 300 len = sizeof(error); 317 301 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 318 return phb_ free(phb, FALSE);302 return phb_close(phb); 319 303 } 320 304 sock_make_blocking(source); 321 305 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); 324 309 } 325 310 … … 328 313 packet[2] = phb->port >> 8; 329 314 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]; 341 319 packet[8] = 0; 342 320 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); 352 322 } 353 323 … … 378 348 379 349 if (read(source, buf, 10) < 10) { 380 return phb_ free(phb, FALSE);350 return phb_close(phb); 381 351 } 382 352 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { 383 return phb_ free(phb, FALSE);353 return phb_close(phb); 384 354 } 385 355 386 356 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; 388 361 } 389 362 … … 404 377 405 378 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { 406 phb_ free(phb, FALSE);379 phb_close(phb); 407 380 return; 408 381 } … … 419 392 420 393 if (read(source, buf, 2) < 2) { 421 return phb_ free(phb, FALSE);394 return phb_close(phb); 422 395 } 423 396 424 397 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { 425 return phb_ free(phb, FALSE);398 return phb_close(phb); 426 399 } 427 400 … … 439 412 440 413 if (read(source, buf, 2) < 2) { 441 return phb_ free(phb, FALSE);414 return phb_close(phb); 442 415 } 443 416 444 417 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { 445 return phb_ free(phb, FALSE);418 return phb_close(phb); 446 419 } 447 420 … … 454 427 memcpy(buf + 2 + i + 1, proxypass, j); 455 428 if (write(source, buf, 3 + i + j) < 3 + i + j) { 456 return phb_ free(phb, FALSE);429 return phb_close(phb); 457 430 } 458 431 … … 478 451 len = sizeof(error); 479 452 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 480 return phb_ free(phb, FALSE);453 return phb_close(phb); 481 454 } 482 455 sock_make_blocking(source); … … 496 469 497 470 if (write(source, buf, i) < i) { 498 return phb_ free(phb, FALSE);471 return phb_close(phb); 499 472 } 500 473 … … 514 487 } 515 488 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 };523 489 524 490 /* Export functions */ … … 527 493 { 528 494 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 }535 495 536 496 if (!host || port <= 0 || !func || strlen(host) > 128) { … … 542 502 phb->data = data; 543 503 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 40 40 #define PROXY_SOCKS4 2 41 41 #define PROXY_SOCKS5 3 42 #define PROXY_SOCKS4A 443 42 44 43 extern char proxyhost[128]; … … 49 48 50 49 G_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);52 50 53 51 #endif /* _PROXY_H_ */ -
lib/ssl_gnutls.c
r3fbce97 r63cad66 455 455 } 456 456 457 proxy_disconnect(conn->fd);457 closesocket(conn->fd); 458 458 459 459 if (conn->session) { -
lib/ssl_nss.c
r3fbce97 r63cad66 226 226 if (conn->prfd) { 227 227 PR_Close(conn->prfd); 228 } else if (source >= 0) {229 /* proxy_disconnect() would be redundant here */228 } 229 if (source >= 0) { 230 230 closesocket(source); 231 231 } … … 305 305 if (conn->prfd) { 306 306 PR_Close(conn->prfd); 307 } else if (conn->fd) {308 proxy_disconnect(conn->fd);309 307 } 310 308 -
lib/ssl_openssl.c
r3fbce97 r63cad66 131 131 conn->func(conn->data, 1, NULL, cond); 132 132 if (source >= 0) { 133 proxy_disconnect(source);133 closesocket(source); 134 134 } 135 135 ssl_conn_free(conn); … … 276 276 } 277 277 278 proxy_disconnect(conn->fd);278 closesocket(conn->fd); 279 279 280 280 ssl_conn_free(conn); -
lib/url.c
r3fbce97 r63cad66 48 48 } else if (g_strncasecmp(set_url, "socks5", i - set_url) == 0) { 49 49 url->proto = PROTO_SOCKS5; 50 } else if (g_strncasecmp(set_url, "socks4a", i - set_url) == 0) {51 url->proto = PROTO_SOCKS4A;52 50 } else { 53 51 return 0; -
lib/url.h
r3fbce97 r63cad66 30 30 #define PROTO_SOCKS4 3 31 31 #define PROTO_SOCKS5 4 32 #define PROTO_SOCKS4A 533 32 #define PROTO_DEFAULT PROTO_HTTP 34 33 -
log.c
r3fbce97 r63cad66 51 51 void log_link(int level, int output) 52 52 { 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 } 67 65 } 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 } 69 75 } 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 } 71 85 } 72 86 #ifdef DEBUG 73 87 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 } 75 97 } 76 98 #endif -
otr.c
r3fbce97 r63cad66 187 187 /* update op/voice flag of given user according to encryption state and settings 188 188 returns 0 if neither op_buddies nor voice_buddies is set to "encrypted", 189 i.e. msgstate should be announced sep arately */189 i.e. msgstate should be announced seperately */ 190 190 int otr_update_modeflags(irc_t *irc, irc_user_t *u); 191 191 … … 216 216 void otr_disconnect_all(irc_t *irc); 217 217 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 222 218 /* functions to be called for certain events */ 223 219 static const struct irc_plugin otr_plugin; 224 225 #define OTR_COLOR_TRUSTED "03" /* green */226 #define OTR_COLOR_UNTRUSTED "05" /* red */227 220 228 221 /*** routines declared in otr.h: ***/ … … 441 434 442 435 /* 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) { 445 437 return msg; 446 438 } … … 459 451 } else if (!newmsg) { 460 452 /* this was a non-OTR message */ 461 return otr_filter_colors(msg);453 return msg; 462 454 } else { 463 455 /* we're done with the original msg, which will be caller-freed. */ … … 480 472 481 473 /* 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) { 484 475 return msg; 485 476 } … … 751 742 } 752 743 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 798 744 void op_convert_msg(void *opdata, ConnContext *ctx, OtrlConvertType typ, 799 745 char **dst, const char *src) … … 806 752 if (typ == OTRL_CONVERT_RECEIVING) { 807 753 char *msg = g_strdup(src); 754 char *buf = msg; 808 755 809 756 /* HTML decoding */ … … 812 759 set_getbool(&ic->bee->set, "strip_html")) { 813 760 strip_html(msg); 814 815 /* msg is borrowed by *dst (unless the next if decides to color it) */816 761 *dst = msg; 817 762 } … … 819 764 /* coloring */ 820 765 if (set_getbool(&ic->bee->set, "otr_color_encrypted")) { 766 int color; /* color according to f'print trust */ 767 char *pre = "", *sep = ""; /* optional parts */ 821 768 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); 830 792 } 831 793 } else { … … 1395 1357 1396 1358 if (u) { 1397 /* just show this as a regular message*/1398 irc_user msg(u, "<<\002OTR\002>>%s", msg);1359 /* display as a notice from this particular user */ 1360 irc_usernotice(u, "%s", msg); 1399 1361 } else { 1400 1362 irc_rootmsg(irc, "[otr] %s", msg); … … 1733 1695 *p = '\0'; 1734 1696 1735 /* remove trailing whitespace */1736 g_strchomp(prefix);1737 1738 1697 /* find first key which matches the given prefix */ 1739 1698 n = strlen(prefix); -
protocols/account.c
r3fbce97 r63cad66 84 84 strstr(a->user, "@googlemail.com")) { 85 85 strcpy(tag, "gtalk"); 86 } else if (strstr(a->user, "@chat.facebook.com")) { 87 strcpy(tag, "fb"); 86 88 } 87 89 } -
protocols/bee.h
r3fbce97 r63cad66 62 62 BEE_USER_LOCAL = 256, /* Locally-added contacts (not in real contact list) */ 63 63 BEE_USER_SPECIAL = 512, /* Denotes a user as being special */ 64 BEE_USER_NOOTR = 4096, /* Per-user version of OPT_NOOTR */65 64 } bee_user_flags_t; 66 65 … … 105 104 gboolean (*user_status)(bee_t *bee, struct bee_user *bu, struct bee_user *old); 106 105 /* 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); 108 107 /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */ 109 108 gboolean (*user_typing)(bee_t *bee, bee_user_t *bu, guint32 flags); … … 118 117 /* System messages of any kind. */ 119 118 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); 121 120 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); 123 122 gboolean (*chat_topic)(bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu); 124 123 gboolean (*chat_name_hint)(bee_t *bee, struct groupchat *c, const char *name); … … 129 128 void (*ft_close)(struct im_connection *ic, struct file_transfer *ft); 130 129 void (*ft_finished)(struct im_connection *ic, struct file_transfer *ft); 131 132 void (*log)(bee_t *bee, const char *tag, const char *msg);133 130 } bee_ui_funcs_t; 134 131 -
protocols/bee_chat.c
r3fbce97 r63cad66 95 95 } 96 96 97 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, guint32flags, time_t sent_at)97 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at) 98 98 { 99 99 struct im_connection *ic = c->ic; 100 100 bee_t *bee = ic->bee; 101 101 bee_user_t *bu; 102 gboolean temp = FALSE;102 gboolean temp; 103 103 char *s; 104 104 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)) { 106 107 return; 107 108 } … … 121 122 122 123 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); 124 125 } 125 126 … … 229 230 230 231 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); 232 233 } 233 234 } -
protocols/bee_user.c
r3fbce97 r63cad66 247 247 } 248 248 249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32flags, time_t sent_at)249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, uint32_t flags, time_t sent_at) 250 250 { 251 251 bee_t *bee = ic->bee; … … 265 265 266 266 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); 268 268 } else { 269 269 imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg); … … 297 297 } 298 298 299 void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32flags)299 void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags) 300 300 { 301 301 bee_user_t *bu; -
protocols/ft.h
r3fbce97 r63cad66 58 58 * | accept 59 59 * V 60 * /------ /-------------\ /------------------------ --\61 * out_of_data | | TRANSFER RING | -----------------> | TRANSFERRING | CANCELED |62 * \-----> \-------------/ [canceled,]free \------------------------ --/60 * /------ /-------------\ /------------------------\ 61 * out_of_data | | TRANSFERING | -----------------> | TRANSFERING | CANCELED | 62 * \-----> \-------------/ [canceled,]free \------------------------/ 63 63 * | 64 64 * | finished,free 65 65 * V 66 * /------------------------ -\67 * | TRANSFER RING | FINISHED |68 * \------------------------ -/66 * /------------------------\ 67 * | TRANSFERING | FINISHED | 68 * \------------------------/ 69 69 */ 70 70 typedef struct file_transfer { … … 115 115 116 116 /* 117 * If set, called after succes sful connection setup.117 * If set, called after succesful connection setup. 118 118 */ 119 119 void (*accept)(struct file_transfer *file); -
protocols/jabber/conference.c
r3fbce97 r63cad66 26 26 27 27 static 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);29 28 30 29 struct groupchat *jabber_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password) … … 122 121 } 123 122 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)); 128 124 } 129 125 130 126 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;137 127 } 138 128 … … 181 171 node = jabber_make_packet("message", "groupchat", jc->name, node); 182 172 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; 186 180 } 187 181 … … 305 299 } 306 300 } 301 302 /* Some program-specific restrictions. */ 303 imcb_clean_handle(ic, bud->ext_jid); 307 304 } 308 305 bud->flags |= JBFLAG_IS_ANONYMOUS; … … 334 331 } else if (type) { /* type can only be NULL or "unavailable" in this function */ 335 332 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 377 333 s = strchr(bud->ext_jid, '/'); 378 334 if (s) { 379 335 *s = 0; 380 336 } 381 imcb_chat_remove_buddy(chat, bud->ext_jid, reason);337 imcb_chat_remove_buddy(chat, bud->ext_jid, NULL); 382 338 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); 384 340 } 385 341 if (s) { 386 342 *s = '/'; 387 343 } 388 389 g_free(reason);390 344 } 391 345 … … 406 360 char *final_from = NULL; 407 361 char *bare_jid = NULL; 408 guint32 flags = 0;409 362 410 363 from = (bud) ? bud->full_jid : xt_find_attr(node, "from"); … … 443 396 444 397 if (subject && chat) { 445 char *subject_text = subject->text_len > 0 ? subject->text : "";398 char *subject_text = subject->text_len > 0 ? subject->text : NULL; 446 399 if (g_strcmp0(chat->topic, subject_text) != 0) { 447 400 bare_jid = (bud) ? jabber_get_bare_jid(bud->ext_jid) : NULL; … … 449 402 jabber_get_timestamp(node)); 450 403 g_free(bare_jid); 451 bare_jid = NULL;452 404 } 453 405 } … … 470 422 imcb_chat_log(chat, "From conference server: %s", body->text); 471 423 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 */ 475 427 return; 476 428 } 477 429 478 if (bud ) {430 if (bud && jc && bud != jc->me) { 479 431 bare_jid = jabber_get_bare_jid(bud->ext_jid ? bud->ext_jid : bud->full_jid); 480 432 final_from = bare_jid; 481 flags = (bud == jc->me) ? OPT_SELFMESSAGE : 0;482 433 } else { 483 434 final_from = nick; 484 435 } 485 436 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)); 487 438 488 439 g_free(bare_jid); -
protocols/jabber/hipchat.c
r3fbce97 r63cad66 42 42 *sep = '/'; 43 43 } 44 45 jd->muc_host = g_strdup(xt_find_attr(node, "muc_host"));46 44 47 45 /* Hipchat's auth doesn't expect a restart here */ … … 94 92 95 93 } 96 97 /* Returns a newly allocated string that tries to match the "slug" part of the JID using an98 * approximation of the method used by the server. This might fail in some rare conditions99 * (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 147 147 } 148 148 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 { 149 static 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) { 209 169 imcb_error(ic, "XML stream error"); 210 170 imc_logout(ic, TRUE); 211 171 return FALSE; 212 172 } 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. */ 238 178 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 } 239 219 } 240 220 } else if (st == 0 || (st < 0 && !ssl_sockerr_again(jd->ssl))) { -
protocols/jabber/iq.c
r3fbce97 r63cad66 28 28 static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 29 29 static 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);31 30 32 31 xt_status jabber_pkt_iq(struct xt_node *node, gpointer data) … … 53 52 (c = xt_find_node(node->children, "time"))) || 54 53 !(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; 60 57 } 61 58 … … 121 118 XMLNS_BYTESTREAMS, 122 119 XMLNS_FILETRANSFER, 123 XMLNS_CARBONS,124 120 NULL }; 125 121 const char **f; … … 138 134 } else { 139 135 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); 141 137 pack = 0; 142 138 } … … 389 385 struct xt_node *response; 390 386 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); 393 389 394 390 jabber_cache_add(ic, response, NULL); … … 1008 1004 { 1009 1005 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"))) { 1030 1009 char *cat, *type, *name; 1031 1010 … … 1044 1023 return XT_HANDLED; 1045 1024 } 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 114 114 s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK; 115 115 116 s = set_add(&acc->set, "carbons", "true", set_eval_bool, acc);117 s->flags |= ACC_SET_OFFLINE_ONLY;118 119 116 acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE | 120 117 ACC_FLAG_HANDLE_DOMAINS; … … 151 148 } 152 149 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 159 150 if ((s = strchr(jd->server, '/'))) { 160 151 *s = 0; … … 176 167 jd->fd = jd->r_inpa = jd->w_inpa = -1; 177 168 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 } 181 174 182 175 oauth_params_parse(&p_in, ic->acc->pass); … … 204 197 } else { 205 198 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;220 199 } 221 200 } … … 287 266 288 267 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); 290 272 } 291 273 … … 352 334 } 353 335 if (jd->fd >= 0) { 354 proxy_disconnect(jd->fd);336 closesocket(jd->fd); 355 337 } 356 338 … … 363 345 } 364 346 365 if (jd->buddies) { 366 jabber_buddy_remove_all(ic); 367 } 347 jabber_buddy_remove_all(ic); 368 348 369 349 xt_free(jd->xt); … … 375 355 g_free(jd->internal_jid); 376 356 g_free(jd->gmail_tid); 377 g_free(jd->muc_host);378 357 g_free(jd->username); 379 358 g_free(jd->me); … … 434 413 } 435 414 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 NULL447 };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 457 415 st = jabber_write_packet(ic, node); 458 416 xt_free_node(node); … … 514 472 static void jabber_add_buddy(struct im_connection *ic, char *who, char *group) 515 473 { 474 struct jabber_data *jd = ic->proto_data; 475 516 476 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); 518 479 return; 519 480 } … … 559 520 } 560 521 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 572 522 if (strchr(room, '@') == NULL) { 573 523 imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?", … … 576 526 imcb_error(ic, "Already present in chat `%s'", room); 577 527 } else { 578 /* jabber_chat_join without the underscore is the conference.c one */579 528 return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password")); 580 529 } … … 641 590 { 642 591 struct jabber_data *jd = ic->proto_data; 643 struct jabber_buddy *bud , *bare;592 struct jabber_buddy *bud; 644 593 645 594 /* Enable typing notification related code from now. */ 646 595 jd->flags |= JFLAG_WANT_TYPING; 647 596 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) { 650 598 /* Sending typing notifications to unknown buddies is 651 599 unsupported for now. Shouldn't be a problem, I think. */ … … 653 601 } 654 602 655 656 if (bud->flags & JBFLAG_DOES_XEP85 || bare->flags & JBFLAG_DOES_XEP85) { 603 if (bud->flags & JBFLAG_DOES_XEP85) { 657 604 /* 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. */ 660 606 661 607 struct xt_node *node; -
protocols/jabber/jabber.h
r3fbce97 r63cad66 50 50 JFLAG_GTALK = 0x100000, /* Is Google Talk, as confirmed by iq discovery */ 51 51 JFLAG_HIPCHAT = 0x200000, /* Is hipchat, because prpl->name says so */ 52 53 JFLAG_SASL_FB = 0x10000, /* Trying Facebook authentication. */ 52 54 } jabber_flags_t; 53 55 … … 111 113 GSList *streamhosts; 112 114 int have_streamhosts; 113 114 char *muc_host;115 115 }; 116 116 … … 228 228 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 229 229 #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 */233 230 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 234 231 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ … … 341 338 342 339 extern const struct oauth2_service oauth2_service_google; 340 extern const struct oauth2_service oauth2_service_facebook; 343 341 344 342 /* conference.c */ … … 358 356 xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 359 357 xt_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);362 358 363 359 #endif -
protocols/jabber/jabber_util.c
r3fbce97 r63cad66 514 514 } else if (bud->resource && (flags & GET_BUDDY_EXACT)) { 515 515 /* 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; 521 517 } else if (bud->resource == NULL || bud->next == NULL) { 522 518 /* No need for selection if there's only one option. */ -
protocols/jabber/message.c
r3fbce97 r63cad66 24 24 #include "jabber.h" 25 25 26 static xt_status jabber_pkt_message_normal(struct xt_node *node, gpointer data, gboolean carbons_sent)26 xt_status jabber_pkt_message(struct xt_node *node, gpointer data) 27 27 { 28 28 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"); 31 30 char *type = xt_find_attr(node, "type"); 32 31 char *id = xt_find_attr(node, "id"); … … 38 37 if (!from) { 39 38 return XT_HANDLED; /* Consider this packet corrupted. */ 39 40 40 } 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) { 54 42 /* 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'> 56 47 * <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> */ 62 49 struct xt_node *received, *receipt; 63 50 … … 140 127 if (fullmsg->len > 0) { 141 128 imcb_buddy_msg(ic, from, fullmsg->str, 142 carbons_sent ? OPT_SELFMESSAGE :0, jabber_get_timestamp(node));129 0, jabber_get_timestamp(node)); 143 130 } 144 131 if (room) { … … 149 136 150 137 /* 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. */ 154 140 } else if (xt_find_node(node->children, "composing")) { 155 141 bud->flags |= JBFLAG_DOES_XEP85; 156 142 imcb_buddy_typing(ic, from, OPT_TYPING); 157 143 } 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)) { 159 146 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); 165 148 } else if (xt_find_node(node->children, "paused")) { 166 149 bud->flags |= JBFLAG_DOES_XEP85; … … 175 158 return XT_HANDLED; 176 159 } 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 186 186 char *prio = set_getstr(&ic->acc->set, "priority"); 187 187 188 if (jd->away_state && jd->away_state->full_name != NULL) {188 if (jd->away_state->code != NULL) { 189 189 int new_prio = (atoi(prio) - 5); 190 190 if (new_prio < 0) { … … 222 222 cap = xt_new_node("c", NULL, NULL); 223 223 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"); 231 225 xt_add_attr(cap, "ver", BITLBEE_VERSION); /* The XEP wants this hashed, but nobody's doing that. */ 232 226 xt_add_child(node, cap); -
protocols/jabber/s5bytestream.c
r3fbce97 r63cad66 536 536 * that sends atyp=0 addrlen=0 and only 6 bytes (one less than one would expect). 537 537 * 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 */ 539 539 540 540 if (bt->tf->ft->sending) { … … 559 559 * An intelligent sender would probably specify himself as the first streamhost and 560 560 * a proxy as the second (Kopete and PSI are examples here). That way, a (potentially) 561 * slow proxy is only used if nec essary. This of course also means, that the timeout561 * slow proxy is only used if neccessary. This of course also means, that the timeout 562 562 * per streamhost should be kept short. If one or two firewalled adresses are specified, 563 563 * they have to timeout first before a proxy is tried. -
protocols/jabber/sasl.c
r3fbce97 r63cad66 38 38 "6C-Zgf7Tr7gEQTPlBhMUgo7R", 39 39 }; 40 const 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 }; 40 49 41 50 xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) … … 45 54 struct xt_node *c, *reply; 46 55 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; 48 57 int want_oauth = FALSE, want_hipchat = FALSE, want_anonymous = FALSE; 49 58 GString *mechs; … … 80 89 } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) { 81 90 sup_gtalk = 1; 91 } else if (c->text && g_strcasecmp(c->text, "X-FACEBOOK-PLATFORM") == 0) { 92 sup_fb = 1; 82 93 } 83 94 … … 90 101 91 102 if (!want_oauth && !sup_plain && !sup_digest) { 92 if (!sup_gtalk ) {103 if (!sup_gtalk && !sup_fb) { 93 104 imcb_error(ic, "This server requires OAuth " 94 105 "(supported schemes:%s)", mechs->str); … … 126 137 reply->text_len = strlen(reply->text); 127 138 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; 128 142 } else if (want_oauth) { 129 143 imcb_error(ic, "OAuth requested, but not supported by server"); … … 140 154 xt_free_node(reply); 141 155 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) { 147 157 xt_add_attr(reply, "mechanism", "DIGEST-MD5"); 148 158 … … 285 295 dec = frombase64(node->text); 286 296 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"))) { 288 318 /* See RFC 2831 for for information. */ 289 319 md5_state_t A1, A2, H; -
protocols/jabber/si.c
r3fbce97 r63cad66 186 186 jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); 187 187 188 /* query buddy's features and server's streaming proxies if nec essary */188 /* query buddy's features and server's streaming proxies if neccessary */ 189 189 190 190 if (!tf->bud->features) { … … 283 283 284 284 if (requestok) { 285 /* Figure out who the transfer should come from ... */285 /* Figure out who the transfer should come frome... */ 286 286 287 287 ext_jid = ini_jid; … … 403 403 * <iq from=... to=... id=...> 404 404 * <si xmlns=si> 405 * [ <file xmlns=ft/> ] <-- not nec essary405 * [ <file xmlns=ft/> ] <-- not neccessary 406 406 * <feature xmlns=feature> 407 407 * <x xmlns=xdata type=submit> -
protocols/msn/gw.c
r3fbce97 r63cad66 22 22 gw->ssl = (GATEWAY_PORT == 443); 23 23 gw->poll_timeout = -1; 24 gw->write_timeout = -1;25 24 gw->ic = ic; 26 25 gw->md = ic->proto_data; … … 35 34 b_event_remove(gw->poll_timeout); 36 35 } 37 38 if (gw->write_timeout != -1) {39 b_event_remove(gw->write_timeout);40 }41 42 36 g_byte_array_free(gw->in, TRUE); 43 37 g_byte_array_free(gw->out, TRUE); … … 195 189 } 196 190 197 static gboolean msn_gw_write_cb(gpointer data, gint source, b_input_condition cond)191 void msn_gw_write(struct msn_gw *gw, char *buf, size_t len) 198 192 { 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); 205 194 if (!gw->open) { 206 195 msn_gw_open(gw); … … 208 197 msn_gw_dorequest(gw, NULL); 209 198 } 210 211 gw->write_timeout = -1;212 return FALSE;213 199 } 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 112 112 113 113 int poll_timeout; 114 int write_timeout;115 114 116 115 b_event_handler callback; -
protocols/msn/msn_util.c
r3fbce97 r63cad66 41 41 } 42 42 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>", 44 44 domain, handle, list); 45 45 } -
protocols/msn/ns.c
r3fbce97 r63cad66 39 39 static void msn_ns_send_adl(struct im_connection *ic); 40 40 static 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);41 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action); 42 42 static void msn_ns_nfy(struct msn_data *md, char *who, char **parts, char *action, gboolean is_put); 43 43 … … 110 110 struct im_connection *ic = md->ic; 111 111 112 /* this should be taken from XFR, but hardcoding it for now. it also prevents more redirects. */113 const char *redir_data = "VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDINCklzR2VvWGZyOiB0cnVlDQo=";114 115 112 if (source == -1 && !md->is_http) { 116 113 imcb_error(ic, "Could not connect to server"); … … 138 135 } 139 136 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)) { 147 138 if (!md->is_http) { 148 139 md->inpa = b_input_add(md->fd, B_EV_IO_READ, msn_ns_callback, md); … … 217 208 } 218 209 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)); 219 212 } else if (strcmp(cmd[0], "CVR") == 0) { 220 213 /* 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); 221 215 } else if (strcmp(cmd[0], "XFR") == 0) { 222 216 char *server; … … 286 280 md->msglen = atoi(cmd[2]); 287 281 } 288 } else if (strcmp(cmd[0], "RML") == 0) {289 /* Move along, nothing to see here */290 282 } else if (strcmp(cmd[0], "CHL") == 0) { 291 283 char *resp; … … 483 475 } 484 476 485 /* returns newly allocated string */ 486 static char *msn_ns_parse_header_address(struct msn_data *md, char *headers, char *header_name) 487 { 477 static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd) 478 { 479 char **parts = NULL; 488 480 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; 494 489 } 495 490 496 491 /* 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); 525 495 526 496 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); 528 498 529 499 } else if ((strcmp(cmd[0], "NFY") == 0) && (action = get_rfc822_header(parts[2], "Uri", 0))) { … … 535 505 g_strfreev(parts); 536 506 g_free(action); 507 g_free(from); 537 508 g_free(who); 538 509 } 539 510 540 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action , gboolean selfmessage)511 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action) 541 512 { 542 513 struct im_connection *ic = md->ic; 543 514 544 if (strcmp(action, "Control/Typing") == 0 && !selfmessage) {515 if (strcmp(action, "Control/Typing") == 0) { 545 516 imcb_buddy_typing(ic, who, OPT_TYPING); 546 517 } 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); 548 519 } 549 520 } … … 624 595 } else { 625 596 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); 633 598 } 634 599 } -
protocols/msn/soap.c
r3fbce97 r63cad66 270 270 struct im_connection *ic = soap_req->ic; 271 271 struct msn_data *md = ic->proto_data; 272 char pass[MAX_PASSPORT_PWLEN + 1]; 272 273 273 274 if (sd->redirect) { … … 285 286 } 286 287 288 strncpy(pass, ic->acc->pass, MAX_PASSPORT_PWLEN); 289 pass[MAX_PASSPORT_PWLEN] = '\0'; 287 290 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); 289 292 290 293 return MSN_SOAP_OK; … … 324 327 struct xt_node *code = xt_find_node(node->children, "faultcode"); 325 328 struct xt_node *string = xt_find_node(node->children, "faultstring"); 326 struct xt_node *reqstatus = xt_find_path(node, "psf:pp/psf:reqstatus");327 329 struct xt_node *url; 328 330 … … 333 335 url->text_len > 0) { 334 336 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);338 337 } else { 339 338 sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ? … … 347 346 { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", msn_soap_passport_sso_token }, 348 347 { "S:Fault", "S:Envelope", msn_soap_passport_failure }, 349 { "S:Fault", "wst:RequestSecurityTokenResponse", msn_soap_passport_failure },350 348 { NULL, NULL, NULL } 351 349 }; … … 776 774 imcb_log(soap_req->ic, "Warning: %d contacts were in both your " 777 775 "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); 779 778 } 780 779 -
protocols/msn/soap.h
r3fbce97 r63cad66 61 61 #define SOAP_PASSPORT_SSO_URL "https://login.live.com/RST.srf" 62 62 #define SOAP_PASSPORT_SSO_URL_MSN "https://msnia.login.live.com/pp900/RST.srf" 63 #define MAX_PASSPORT_PWLEN 16 63 64 64 65 #define SOAP_PASSPORT_SSO_PAYLOAD \ -
protocols/nogaim.c
r3fbce97 r63cad66 90 90 91 91 GList *protocols = NULL; 92 GList *disabled_protocols = NULL;93 92 94 93 void register_protocol(struct prpl *p) … … 104 103 105 104 if (refused) { 106 disabled_protocols = g_list_append(disabled_protocols, p);105 log_message(LOGLVL_WARNING, "Protocol %s disabled\n", p->name); 107 106 } else { 108 107 protocols = g_list_append(protocols, p); … … 110 109 } 111 110 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 118 111 struct prpl *find_protocol(const char *name) 119 112 { 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; 127 124 } 128 125 … … 212 209 account_t *a; 213 210 214 if (!ic->bee->ui->log) {215 return;216 }217 218 211 va_start(params, format); 219 212 text = g_strdup_vprintf(format, params); … … 234 227 /* If we found one, include the screenname in the message. */ 235 228 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); 237 231 } else { 238 i c->bee->ui->log(ic->bee, ic->acc->prpl->name, text);232 irc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text); 239 233 } 240 234 … … 668 662 GList *m = ic->acc->prpl->away_states(ic); 669 663 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; 672 665 } else if (ic->acc->flags & ACC_FLAG_STATUS_MESSAGE) { 673 666 away = NULL; … … 788 781 } 789 782 790 /* Deprecated: using this function resulted in merging several handles accidentally791 * Also the irc layer handles this decently nowadays */792 783 void imcb_clean_handle(struct im_connection *ic, char *handle) 793 784 { 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 76 76 #define OPT_PONGED 0x00020000 /* Received a keep-alive during last interval */ 77 77 #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 */79 78 80 79 /* ok. now the fun begins. first we create a connection structure */ … … 281 280 G_MODULE_EXPORT GSList *get_connections(); 282 281 G_MODULE_EXPORT struct prpl *find_protocol(const char *name); 283 G_MODULE_EXPORT gboolean is_protocol_disabled(const char *name);284 282 /* When registering a new protocol, you should allocate space for a new prpl 285 283 * struct, initialize it (set the function pointers to point to your … … 328 326 G_MODULE_EXPORT void imcb_add_buddy(struct im_connection *ic, const char *handle, const char *group); 329 327 G_MODULE_EXPORT void imcb_remove_buddy(struct im_connection *ic, const char *handle, char *group); 328 G_MODULE_EXPORT struct buddy *imcb_find_buddy(struct im_connection *ic, char *handle); 330 329 G_MODULE_EXPORT void imcb_rename_buddy(struct im_connection *ic, const char *handle, const char *realname); 331 330 G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick); … … 333 332 G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic); 334 333 335 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32flags);334 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags); 336 335 G_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); 336 G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle); 339 337 340 338 /* Actions, or whatever. */ -
protocols/oscar/aim.h
r3fbce97 r63cad66 21 21 22 22 #include "bitlbee.h" 23 24 #ifdef WITH_PURPLE25 /* For compatibility with builds that include both purple and this oscar module */26 #include "aim_prefixes.h"27 #endif28 23 29 24 /* XXX adjust these based on autoconf-detected platform */ … … 876 871 * SNAC Family: Internal Messages 877 872 * 878 * This isn't tru ly a SNAC family either, but using873 * This isn't truely a SNAC family either, but using 879 874 * these, we can integrated non-SNAC services into 880 875 * the SNAC-centered libfaim callback structure. -
protocols/oscar/auth.c
r3fbce97 r63cad66 41 41 * meaning you generally never call this. 42 42 * 43 * But there are times when something might want it sep arate. Specifically,43 * But there are times when something might want it seperate. Specifically, 44 44 * libfaim sends this internally when doing SNAC login. 45 45 * -
protocols/oscar/conn.c
r3fbce97 r63cad66 15 15 * In OSCAR, every connection has a set of SNAC groups associated 16 16 * with it. These are the groups that you can send over this connection 17 * without being guar anteed a "Not supported" SNAC error.17 * without being guarenteed a "Not supported" SNAC error. 18 18 * 19 19 * The grand theory of things says that these associations transcend … … 36 36 * 37 37 * Here comes the good bit. Without even letting anyone know, particularly 38 * the module that decided to send this SNAC, and definit ely not that twit38 * the module that decided to send this SNAC, and definitly not that twit 39 39 * in Greenland, you send out a service request. In this request, you have 40 40 * marked the need for a connection supporting group 0x000e. A few seconds … … 317 317 318 318 if (deadconn->fd >= 3) { 319 proxy_disconnect(deadconn->fd);319 closesocket(deadconn->fd); 320 320 } 321 321 deadconn->fd = -1; -
protocols/oscar/im.c
r3fbce97 r63cad66 50 50 * encoding for your message. In UNICODE mode, _all_ characters must 51 51 * occupy 16bits, including ones that are not special. (Remember that 52 * the first 128 UNICODE symbols are equiv alent to ASCII7, however they52 * the first 128 UNICODE symbols are equivelent to ASCII7, however they 53 53 * must be prefixed with a zero high order byte.) 54 54 * … … 64 64 * in all of libfaim, it is written with performance in mind. As such, 65 65 * it is not as clear as it could be in respect to how this message is 66 * supposed to be la id out. Most obviously, tlvlists should be used66 * supposed to be layed out. Most obviously, tlvlists should be used 67 67 * instead of writing out the bytes manually. 68 68 * … … 476 476 * examples of how to do this. 477 477 * 478 * I would definit ely recommend avoiding this feature unless you really478 * I would definitly recommend avoiding this feature unless you really 479 479 * know what you are doing, and/or you have something neat to do with it. 480 480 * … … 638 638 } 639 639 #if 0 640 /* XXX this isn't really neces sary... */640 /* XXX this isn't really necesary... */ 641 641 if (((args.flag1 != 0x0000) && 642 642 (args.flag1 != 0x0002) && … … 1161 1161 * 1162 1162 * Channel 0x0001 is the message channel. There are 1163 * other channels for things called "rende zvous"1163 * other channels for things called "rendevous" 1164 1164 * which represent chat and some of the other new 1165 1165 * features of AIM2/3/3.5. 1166 1166 * 1167 * Channel 0x0002 is the Rende zvous channel, which1167 * Channel 0x0002 is the Rendevous channel, which 1168 1168 * is where Chat Invitiations and various client-client 1169 1169 * connection negotiations come from. … … 1181 1181 * with the TLVs read below, they are two different pieces. The 1182 1182 * userinfo block contains the number of TLVs that contain user 1183 * information, the rest are not even though there is no sep aration.1183 * information, the rest are not even though there is no seperation. 1184 1184 * aim_extractuserinfo() returns the number of bytes used by the 1185 1185 * userinfo tlvs, so you can start reading the rest of them right … … 1253 1253 /* 1254 1254 * 1255 * I definit ely recommend sending this. If you don't, you'll be stuck1255 * I definitly recommend sending this. If you don't, you'll be stuck 1256 1256 * with the rather unreasonable defaults. You don't want those. Send this. 1257 1257 * -
protocols/oscar/misc.c
r3fbce97 r63cad66 3 3 * aim_misc.c 4 4 * 5 * TODO: Sep arate a lot of this into an aim_bos.c.5 * TODO: Seperate a lot of this into an aim_bos.c. 6 6 * 7 7 * Other things... -
protocols/oscar/msgcookie.c
r3fbce97 r63cad66 142 142 * @cookiep: the address of a pointer to the cookie struct to remove 143 143 * 144 * this function removes the cookie *cookie from t helist of cookies144 * this function removes the cookie *cookie from teh list of cookies 145 145 * in sess, and then frees all memory associated with it. including 146 146 * its data! if you want to use the private data after calling this, -
protocols/oscar/oscar.c
r3fbce97 r63cad66 1266 1266 } break; 1267 1267 1268 case 2: { /* rende zvous */1268 case 2: { /* rendevous */ 1269 1269 struct aim_incomingim_ch2_args *args; 1270 1270 args = va_arg(ap, struct aim_incomingim_ch2_args *); -
protocols/oscar/rxhandlers.c
r3fbce97 r63cad66 381 381 /* 382 382 * This doesn't have to be called here. It could easily be done 383 * by a sep arate thread or something. It's an administrative operation,383 * by a seperate thread or something. It's an administrative operation, 384 384 * and can take a while. Though the less you call it the less memory 385 385 * you'll have :) -
protocols/oscar/rxqueue.c
r3fbce97 r63cad66 361 361 /* 362 362 * Grab a single command sequence off the socket, and enqueue 363 * it in the incoming event queue in a sep arate struct.363 * it in the incoming event queue in a seperate struct. 364 364 */ 365 365 int aim_get_command(aim_session_t *sess, aim_conn_t *conn) … … 479 479 480 480 /* 481 * Purge rec eive queue of all handled commands (->handled==1). Also481 * Purge recieve queue of all handled commands (->handled==1). Also 482 482 * allows for selective freeing using ->nofree so that the client can 483 483 * keep the data for various purposes. -
protocols/oscar/service.c
r3fbce97 r63cad66 157 157 158 158 /* 159 * OSCAR defines several 'rate classes'. Each class has sep arate159 * OSCAR defines several 'rate classes'. Each class has seperate 160 160 * rate limiting properties (limit level, alert level, disconnect 161 161 * level, etc), and a set of SNAC family/type pairs associated with … … 709 709 * of memory. (I won't put it past them to start requesting data in 710 710 * less static regions -- regions that are initialized at run time, but still 711 * before the client rec eives this request.)712 * 713 * When the client rec eives the request, it adds it to the current ds711 * before the client recieves this request.) 712 * 713 * When the client recieves the request, it adds it to the current ds 714 714 * (0x00400000) and dereferences it, copying the data into a buffer which 715 715 * it then runs directly through the MD5 hasher. The 16 byte output of … … 723 723 * download a FREE, fully featured, and authorized client, here 724 724 * http://www.aol.com/aim/download2.html" 725 * The connection is then closed, rec eiving disconnect code 1, URL725 * The connection is then closed, recieving disconnect code 1, URL 726 726 * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html. 727 727 * 728 728 * Note, however, that numerous inconsistencies can cause the above error, 729 * not just sending back a bad hash. Do not immediat ely suspect this code729 * not just sending back a bad hash. Do not immediatly suspect this code 730 730 * if you get disconnected. AOL and the open/free software community have 731 731 * played this game for a couple years now, generating the above message 732 * on numerous oc casions.732 * on numerous ocassions. 733 733 * 734 734 * Anyway, neener. We win again. -
protocols/oscar/tlv.c
r3fbce97 r63cad66 25 25 * bstream references, so that at least the ->value portion of each 26 26 * element doesn't need to be malloc/memcpy'd. This could prove to be 27 * just as eff icient as the in-place TLV parsing used in a couple places27 * just as effecient as the in-place TLV parsing used in a couple places 28 28 * in libfaim. 29 29 * … … 135 135 /** 136 136 * aim_addtlvtochain_str - Add a string to a TLV chain 137 * @list: Desi gnation chain (%NULL pointer if empty)137 * @list: Desination chain (%NULL pointer if empty) 138 138 * @type: TLV type 139 139 * @str: String to add -
protocols/oscar/txqueue.c
r3fbce97 r63cad66 67 67 * The overall purpose here is to enqueue the passed in command struct 68 68 * into the outgoing (tx) queue. Basically... 69 * 1) Make a scope-irrelev ant copy of the struct69 * 1) Make a scope-irrelevent copy of the struct 70 70 * 3) Mark as not-sent-yet 71 71 * 4) Enqueue the struct into the list -
protocols/purple/ft-direct.c
r3fbce97 r63cad66 193 193 PurpleXferUiOps bee_xfer_uiops = 194 194 { 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, 204 204 }; 205 205 -
protocols/purple/ft.c
r3fbce97 r63cad66 232 232 } 233 233 234 static void prplcb_xfer_dbg(PurpleXfer *xfer) 235 { 236 fprintf(stderr, "prplcb_xfer_dbg 0x%p\n", xfer); 237 } 238 234 239 235 240 /* Sending files (UI->IM): */ … … 332 337 PurpleXferUiOps bee_xfer_uiops = 333 338 { 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, 343 348 }; -
protocols/purple/purple.c
r3fbce97 r63cad66 113 113 servers anyway! */ 114 114 if (!dir_fixed) { 115 PurpleCertificatePool *pool;116 115 irc_t *irc = acc->bee->ui_data; 117 116 char *dir; … … 123 122 purple_blist_load(); 124 123 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 137 124 dir_fixed = TRUE; 138 125 } … … 365 352 if (!pd) { 366 353 return; 367 }368 369 while (ic->groupchats) {370 imcb_chat_free(ic->groupchats->data);371 354 } 372 355 … … 656 639 /* Call the fucker. */ 657 640 callback = (void *) mi->callback; 658 callback(&pb->node, m i->data);641 callback(&pb->node, menu->data); 659 642 660 643 return NULL; … … 724 707 g_hash_table_replace(chat_hash, "passwd", g_strdup(password)); 725 708 } 726 727 g_free(pce); 728 } 729 730 g_list_free(info); 709 } 731 710 732 711 serv_join_chat(purple_account_get_connection(pd->account), chat_hash); 733 712 734 g_hash_table_destroy(chat_hash); 735 736 return imcb_chat_new(ic, room); 713 return NULL; 737 714 } 738 715 … … 756 733 static PurpleCoreUiOps bee_core_uiops = 757 734 { 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, 763 740 }; 764 741 … … 787 764 purple_gg_buddylist_import(gc); 788 765 789 ic->flags |= OPT_DOES_HTML; 766 if (gc->flags & PURPLE_CONNECTION_HTML) { 767 ic->flags |= OPT_DOES_HTML; 768 } 790 769 } 791 770 … … 821 800 static PurpleConnectionUiOps bee_conn_uiops = 822 801 { 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, 831 810 }; 832 811 … … 903 882 static PurpleBlistUiOps bee_blist_uiops = 904 883 { 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, 910 889 }; 911 890 … … 916 895 struct groupchat *gc; 917 896 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); 929 900 imcb_chat_topic(gc, NULL, conv->title, 0); 930 901 } … … 969 940 } 970 941 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); 942 void prplcb_conv_chat_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, 943 time_t mtime) 944 { 975 945 struct groupchat *gc = conv->ui_data; 976 946 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 } 977 952 978 953 buddy = purple_find_buddy(conv->account, who); … … 981 956 } 982 957 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 961 static 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. */ 1005 968 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); 1008 978 } 1009 979 … … 1038 1008 prplcb_conv_new, /* create_conversation */ 1039 1009 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 */ 1043 1013 prplcb_conv_add_users, /* chat_add_users */ 1044 1014 NULL, /* chat_rename_user */ … … 1205 1175 static PurpleRequestUiOps bee_request_uiops = 1206 1176 { 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, 1214 1184 }; 1215 1185 … … 1252 1222 static PurplePrivacyUiOps bee_privacy_uiops = 1253 1223 { 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, 1258 1228 }; 1259 1229 … … 1265 1235 static PurpleDebugUiOps bee_debug_uiops = 1266 1236 { 1267 prplcb_debug_print, /* print */1237 prplcb_debug_print, 1268 1238 }; 1269 1239 … … 1286 1256 static PurpleEventLoopUiOps glib_eventloops = 1287 1257 { 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, 1292 1262 }; 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 }1314 1263 1315 1264 static void *prplcb_notify_email(PurpleConnection *gc, const char *subject, const char *from, … … 1373 1322 static PurpleNotifyUiOps bee_notify_uiops = 1374 1323 { 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, 1382 1331 }; 1383 1332 … … 1406 1355 static PurpleAccountUiOps bee_account_uiops = 1407 1356 { 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, 1413 1362 }; 1414 1363 … … 1438 1387 char *dir; 1439 1388 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 } 1442 1394 1443 1395 dir = g_strdup_printf("%s/purple", global.conf->configdir); … … 1457 1409 PurpleProxyInfo *pi = purple_global_proxy_get_info(); 1458 1410 switch (proxytype) { 1459 case PROXY_SOCKS4A:1460 1411 case PROXY_SOCKS4: 1461 1412 purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS4); -
protocols/skype/README
r3fbce97 r63cad66 203 203 204 204 * `account skype set skypeconsole_receive true` will make the 205 `skypeconsole` account dump all the rec eived raw traffic for you205 `skypeconsole` account dump all the recieved raw traffic for you 206 206 207 207 - If you want to automatically join bookmarked groupchats right after -
protocols/skype/skype.c
r3fbce97 r63cad66 21 21 22 22 #define _XOPEN_SOURCE 23 #define _BSD_SOURCE 23 24 #include <poll.h> 24 25 #include <stdio.h> … … 187 188 188 189 va_start(args, fmt); 189 g_vsnprintf(str, IRC_LINE_SIZE, fmt, args);190 vsnprintf(str, IRC_LINE_SIZE, fmt, args); 190 191 va_end(args); 191 192 … … 321 322 } 322 323 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;341 324 } 342 325 … … 705 688 info += 9; 706 689 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); 708 691 int i; 709 692 for (i = 0; i < g_list_length(sd->body); i++) { … … 1043 1026 } 1044 1027 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); 1046 1035 } 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); 1048 1038 /* According to the docs this 1049 1039 * is necessary. However it … … 1056 1046 sd->groupchat_with); 1057 1047 imcb_chat_add_buddy(gc, buf); 1048 imcb_chat_add_buddy(gc, sd->username); 1058 1049 g_free(sd->groupchat_with); 1059 1050 sd->groupchat_with = NULL; 1051 skype_printf(ic, "GET CHAT %s ADDER\n", id); 1052 skype_printf(ic, "GET CHAT %s TOPIC\n", id); 1060 1053 } else if (!strcmp(info, "STATUS UNSUBSCRIBED")) { 1061 1054 gc = bee_chat_by_title(ic->bee, ic, id); … … 1264 1257 } 1265 1258 g_strfreev(lines); 1266 } else if (st == 0 || (st < 0 && !s sl_sockerr_again(sd->ssl))) {1259 } else if (st == 0 || (st < 0 && !sockerr_again())) { 1267 1260 ssl_disconnect(sd->ssl); 1268 1261 sd->fd = -1; -
protocols/skype/t/add-yes-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/added-no-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/added-yes-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/away-set-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/call-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :alice -
protocols/skype/t/call-failed-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :alice -
protocols/skype/t/called-no-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/called-yes-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/ctcp-help-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/filetransfer-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/group-add-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/group-read-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/groupchat-invite-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 7 7 >> :bob!bob@skype.com JOIN :&bitlbee 8 8 << PRIVMSG &bitlbee :chat with bob 9 >> 353 alice = ##alice/$bob;a7ab206ec78 :@alice@root10 << 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 26 26 >> GET CHAT #alice/$bob;a7ab206ec78060f1 TOPIC 27 27 << CHAT #alice/$bob;a7ab206ec78060f1 TOPIC 28 >> GET CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS29 << CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS30 28 << CHATMESSAGE 206 STATUS SENDING 31 29 << CHAT #alice/$bob;a7ab206ec78060f1 STATUS DIALOG -
protocols/skype/t/groupchat-invited-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 5 5 << PRIVMSG &bitlbee :account add skype alice foo 6 6 << PRIVMSG &bitlbee :account skype on 7 >> JOIN :##cecil/$bob;4d8cc996579 8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice@root7 >> 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 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 6 6 << PRIVMSG &bitlbee :account skype set skypeconsole_receive true 7 7 << PRIVMSG &bitlbee :account skype on 8 >> JOIN :##cecil/$bob;4d8cc996579 9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice@root10 << PART ##cecil/$bob;4d8cc996579 8 >> JOIN :##cecil/$bob;4d8cc9965791 9 >> 353 alice = ##cecil/$bob;4d8cc9965791 :@alice bob cecil @root 10 << PART ##cecil/$bob;4d8cc9965791 11 11 >> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 STATUS UNSUBSCRIBED -
protocols/skype/t/groupchat-leave-skyped.mock
r3fbce97 r63cad66 36 36 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 37 37 << 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 40 46 >> GET CHATMESSAGE 188 FROM_HANDLE 41 47 << CHATMESSAGE 188 FROM_HANDLE bob -
protocols/skype/t/groupchat-msg-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 6 6 << PRIVMSG &bitlbee :account skype set skypeconsole_receive true 7 7 << PRIVMSG &bitlbee :account skype on 8 >> JOIN :##cecil/$bob;4d8cc996579 9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice@root10 << PRIVMSG ##cecil/$bob;4d8cc996579 :hello8 >> JOIN :##cecil/$bob;4d8cc9965791 9 >> 353 alice = ##cecil/$bob;4d8cc9965791 :@alice bob cecil @root 10 << PRIVMSG ##cecil/$bob;4d8cc9965791 :hello 11 11 >> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVITY_TIMESTAMP -
protocols/skype/t/groupchat-msg-skyped.mock
r3fbce97 r63cad66 36 36 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 37 37 << 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 40 46 >> GET CHATMESSAGE 188 FROM_HANDLE 41 47 << CHATMESSAGE 188 FROM_HANDLE bob -
protocols/skype/t/groupchat-topic-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice … … 5 5 << PRIVMSG &bitlbee :account add skype alice foo 6 6 << PRIVMSG &bitlbee :account skype on 7 >> JOIN :##cecil/$bob;4d8cc996579 8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice@root9 << TOPIC ##cecil/$bob;4d8cc996579 :topic10 >> TOPIC ##cecil/$bob;4d8cc996579 :topic7 >> 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 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/login-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/msg-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/set-mood-text-bitlbee.mock
r3fbce97 r63cad66 1 >> NOTICE *1 >> NOTICE AUTH 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/twitter/twitter.c
r3fbce97 r63cad66 678 678 ic->flags &= ~OPT_LOGGED_IN; 679 679 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 680 687 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 688 688 if (td->filter_update_id > 0) { 689 689 b_event_remove(td->filter_update_id); -
protocols/twitter/twitter_http.c
r3fbce97 r63cad66 24 24 /***************************************************************************\ 25 25 * * 26 * Some fun ctions within this file have been copied from other files within *26 * Some funtions within this file have been copied from other files within * 27 27 * BitlBee. * 28 28 * * … … 53 53 char *tmp; 54 54 GString *request = g_string_new(""); 55 void *ret = NULL;55 void *ret; 56 56 char *url_arguments; 57 57 url_t *base_url = NULL; … … 72 72 base_url = g_new0(url_t, 1); 73 73 if (!url_set(base_url, url_string)) { 74 goto error; 74 g_free(base_url); 75 return NULL; 75 76 } 76 77 } … … 131 132 } 132 133 133 error:134 134 g_free(url_arguments); 135 135 g_string_free(request, TRUE); -
protocols/twitter/twitter_lib.c
r3fbce97 r63cad66 314 314 td = ic->proto_data; 315 315 316 txl = g_new0(struct twitter_xml_list, 1); 317 txl->list = td->follow_ids; 318 316 319 // Parse the data. 317 320 if (!(parsed = twitter_parse_response(ic, req))) { 318 321 return; 319 322 } 320 321 txl = g_new0(struct twitter_xml_list, 1);322 txl->list = td->follow_ids;323 323 324 324 twitter_xt_get_friends_id_list(parsed, txl); … … 390 390 } 391 391 392 txl = g_new0(struct twitter_xml_list, 1); 393 txl->list = NULL; 394 392 395 // Get the user list from the parsed xml feed. 393 396 if (!(parsed = twitter_parse_response(ic, req))) { 394 397 return; 395 398 } 396 397 txl = g_new0(struct twitter_xml_list, 1);398 txl->list = NULL;399 400 399 twitter_xt_get_users(parsed, txl); 401 400 json_value_free(parsed); … … 1390 1389 td = ic->proto_data; 1391 1390 1391 txl = g_new0(struct twitter_xml_list, 1); 1392 txl->list = NULL; 1393 1392 1394 // The root <statuses> node should hold the list of statuses <status> 1393 1395 if (!(parsed = twitter_parse_response(ic, req))) { 1394 1396 goto end; 1395 1397 } 1396 1397 txl = g_new0(struct twitter_xml_list, 1);1398 txl->list = NULL;1399 1400 1398 twitter_xt_get_status_list(ic, parsed, txl); 1401 1399 json_value_free(parsed); … … 1430 1428 td = ic->proto_data; 1431 1429 1430 txl = g_new0(struct twitter_xml_list, 1); 1431 txl->list = NULL; 1432 1432 1433 // The root <statuses> node should hold the list of statuses <status> 1433 1434 if (!(parsed = twitter_parse_response(ic, req))) { 1434 1435 goto end; 1435 1436 } 1436 1437 txl = g_new0(struct twitter_xml_list, 1);1438 txl->list = NULL;1439 1440 1437 twitter_xt_get_status_list(ic, parsed, txl); 1441 1438 json_value_free(parsed); -
protocols/yahoo/libyahoo2.c
r3fbce97 r63cad66 12 12 * GNU GPL. 13 13 * 14 * This code is deriv ative of Gaim <http://gaim.sourceforge.net>14 * This code is derivitive of Gaim <http://gaim.sourceforge.net> 15 15 * copyright (C) 1998-1999, Mark Spencer <markster@marko.net> 16 16 * 1998-1999, Adam Fritzler <afritz@marko.net> … … 1402 1402 1403 1403 /* 1404 * Status updates may be spread ac ross multiple packets and not1404 * Status updates may be spread accross multiple packets and not 1405 1405 * even on buddy boundaries, so keeping some state is important. 1406 1406 * So, continue where we left off, and only add a user entry to -
protocols/yahoo/yahoo.c
r3fbce97 r63cad66 440 440 { 441 441 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)) { 453 444 g_free(d); 454 445 return; -
protocols/yahoo/yahoo2_callbacks.h
r3fbce97 r63cad66 685 685 * Name: ext_yahoo_connect_async 686 686 * Connect to a host:port asynchronously. This function should return 687 * immediately retur ning a tag used to identify the connection handler,687 * immediately returing a tag used to identify the connection handler, 688 688 * or a pre-connect error (eg: host name lookup failure). 689 689 * Once the connect completes (successfully or unsuccessfully), callback -
root_commands.c
r3fbce97 r63cad66 163 163 irc_umode_set(irc, "+R", 1); 164 164 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 171 165 bitlbee_whatsnew(irc); 172 166 … … 244 238 irc->status |= USTATUS_IDENTIFIED; 245 239 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 }252 240 253 241 /* Set this var now, or anyone who logs in to his/her … … 425 413 426 414 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"); 432 416 return; 433 417 } -
tests/Makefile
r3fbce97 r63cad66 15 15 distclean: clean 16 16 17 main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_c ap.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.o17 main_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 18 18 19 19 test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_set.o check_jabber_sasl.o check_jabber_util.o -
tests/check.c
r3fbce97 r63cad66 42 42 gettimeofday(time, 0); 43 43 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 */49 44 } 50 45 -
tests/check_jabber_util.c
r3fbce97 r63cad66 37 37 fail_unless(jabber_buddy_by_jid(ic, "wilmer@GAAST.NET/BitlBee", GET_BUDDY_CREAT) == budw1); 38 38 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)); 40 40 fail_unless(jabber_buddy_by_jid(ic, "WILMER@gaast.net", 0) == budw3); 41 41 … … 105 105 } 106 106 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 126 107 Suite *jabber_util_suite(void) 127 108 { … … 140 121 tcase_add_test(tc_core, check_buddy_add); 141 122 tcase_add_test(tc_core, check_compareJID); 142 tcase_add_test(tc_core, check_hipchat_slug);143 123 return s; 144 124 } -
tests/check_user.c
r3fbce97 r63cad66 46 46 END_TEST 47 47 48 START_TEST(test_user_del_nonexist ent)48 START_TEST(test_user_del_nonexistant) 49 49 irc_t * irc = torture_irc(); 50 50 fail_unless(user_del(irc, "foo") == 0); … … 71 71 tcase_add_test(tc_core, test_user_add_exists); 72 72 tcase_add_test(tc_core, test_user_del_invalid); 73 tcase_add_test(tc_core, test_user_del_nonexist ent);73 tcase_add_test(tc_core, test_user_del_nonexistant); 74 74 tcase_add_test(tc_core, test_user_del); 75 75 tcase_add_test(tc_core, test_user_rename); -
unix.c
r3fbce97 r63cad66 48 48 global_t global; /* Against global namespace pollution */ 49 49 50 static struct { 51 int fd[2]; 52 int tag; 53 } shutdown_pipe = {{-1 , -1}, 0}; 54 50 static int signal_shutdown_pipe[2] = { -1, -1 }; 55 51 static void sighandler_shutdown(int signal); 56 52 static void sighandler_crash(int signal); … … 160 156 sigaction(SIGSEGV, &sig, &old); 161 157 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 } 167 165 168 166 if (!getuid() || !geteuid()) { … … 258 256 } 259 257 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 275 258 /* Signal handler for SIGTERM and SIGINT */ 276 259 static void sighandler_shutdown(int signal) … … 278 261 /* Write a single null byte to the pipe, just to send a message to the main loop. 279 262 * This gets handled by bitlbee_shutdown (the b_input_add callback for this pipe) */ 280 write(s hutdown_pipe.fd[1], "", 1);263 write(signal_shutdown_pipe[1], "", 1); 281 264 } 282 265 … … 292 275 for (l = irc_connection_list; l; l = l->next) { 293 276 irc_t *irc = l->data; 294 sock_make_blocking(irc->fd);295 277 write(irc->fd, message, len); 296 278 }
Note: See TracChangeset
for help on using the changeset viewer.