Changeset 29ff5c2
- Timestamp:
- 2015-11-21T00:01:50Z (8 years ago)
- Parents:
- e4f08bf (diff), 8fdeaa5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 1 added
- 107 edited
Legend:
- Unmodified
- Added
- Removed
-
.travis.yml
re4f08bf r29ff5c2 1 sudo: false 1 2 language: c 2 3 … … 4 5 - ./configure 5 6 - make check 6 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us 7 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d 7 8 9 # ubuntu precise doesn't have libotr5, so extract a prebuilt version to ~/otr 8 10 before_install: 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 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 13 16 14 17 env: 15 18 global: 19 - PKG_CONFIG_PATH=$HOME/otr/usr/lib/pkgconfig/ 20 - LD_LIBRARY_PATH=$HOME/otr/usr/lib/ 16 21 # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created 17 22 # via the "travis encrypt" command using the project repo's public key … … 19 24 20 25 addons: 26 apt: 27 packages: 28 - libevent-dev 29 - libpurple-dev 30 - check 21 31 coverity_scan: 22 32 project: -
Makefile
re4f08bf r29ff5c2 10 10 11 11 # Program variables 12 objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_c hannel.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_cap.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o $(OTR_BI) query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o conf.o log.o 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 @echo 33 @echo Installed successfully 34 @echo 32 35 @if ! [ -d $(DESTDIR)$(CONFIG) ]; then echo -e '\nThe configuration directory $(DESTDIR)$(CONFIG) does not exist yet, don'\''t forget to create it!'; fi 33 36 @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 … … 35 38 @echo If you want to start BitlBee using systemd, try \"make install-systemd\". 36 39 endif 37 @echo 38 39 .PHONY: install install-bin install-etc install-doc install-plugins install-systemd \ 40 uninstall uninstall-bin uninstall-etc uninstall-doc \ 40 @echo To be able to compile third party plugins, run \"make install-dev\" 41 @echo 42 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 \ 41 45 all clean distclean tar $(subdirs) doc 42 46 -
README.md
re4f08bf r29ff5c2 16 16 License: GPLv2 17 17 18 ## Development18 ## Installation 19 19 20 Use github pull requests against the 'develop' branch to submit patches.20 BitlBee is available in the package managers of most distros. 21 21 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. 22 For debian/ubuntu/etc you may use the nightly APT repository: http://code.bitlbee.org/debian/ 23 23 24 Building: 24 You can also use a public server (such as `im.bitlbee.org`) instead of installing it: http://bitlbee.org/main.php/servers.html 25 25 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 26 ## Compiling 30 27 31 # Also try --asan=1 for AddressSanitizer 28 If you wish to compile it yourself, ensure you have the following packages and their headers: 32 29 33 make 30 * glib 2.16 or newer (not to be confused with glibc) 31 * gnutls 32 * python 2 or 3 (for the user guide) 34 33 35 BITLBEE_DEBUG=1 ./bitlbee -Dnv 36 ``` 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. 37 36 38 See ./doc/README and ./doc/HACKING for more details. 37 Once you have the dependencies, building should be a matter of: 39 38 40 Mappings of bzr revisions to git commits (for historical purposes) are available in ./doc/git-bzr-rev-map 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` 41 51 42 52 ## Help? 43 53 44 Join **#BitlBee** on OFTC (**irc.oftc.net**) (OFTC, *not* FreeNode!) and flame us right in the face. :-)54 Join **#BitlBee** on OFTC (**irc.oftc.net**) (OFTC, *not* FreeNode!) -
bitlbee.c
re4f08bf r29ff5c2 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 313 316 /* Make the connection. */ 314 317 irc = irc_new(new_socket); -
bitlbee.h
re4f08bf r29ff5c2 36 36 37 37 #define PACKAGE "BitlBee" 38 #define BITLBEE_VERSION "3.4 "38 #define BITLBEE_VERSION "3.4.1" 39 39 #define VERSION BITLBEE_VERSION 40 40 #define BITLBEE_VER(a, b, c) (((a) << 16) + ((b) << 8) + (c)) 41 #define BITLBEE_VERSION_CODE BITLBEE_VER(3, 4, 0)41 #define BITLBEE_VERSION_CODE BITLBEE_VER(3, 4, 1) 42 42 43 43 #define MAX_STRING 511 … … 158 158 } global_t; 159 159 160 void sighandler_shutdown_setup(void); 161 160 162 int bitlbee_daemon_init(void); 161 163 int bitlbee_inetd_init(void); -
conf.c
re4f08bf r29ff5c2 37 37 38 38 static int conf_loadini(conf_t *conf, char *file); 39 static void conf_free(conf_t *conf); 39 40 40 41 conf_t *conf_load(int argc, char *argv[]) … … 73 74 if (i == 0) { 74 75 fprintf(stderr, "Error: Syntax error in configuration file `%s'.\n", global.conf_file); 76 conf_free(conf); 75 77 return NULL; 76 78 } else if (i == -1) { … … 104 106 g_free(global.conf_file); 105 107 global.conf_file = g_strdup(optarg); 106 g_free(conf);108 conf_free(conf); 107 109 /* Re-evaluate arguments. Don't use this option twice, 108 110 you'll end up in an infinite loop! Hope this trick … … 135 137 " -h Show this help page.\n" 136 138 " -V Show version info.\n"); 139 conf_free(conf); 137 140 return NULL; 138 141 } else if (opt == 'V') { 139 142 printf("BitlBee %s\nAPI version %06x\n", 140 143 BITLBEE_VERSION, BITLBEE_VERSION_CODE); 144 conf_free(conf); 141 145 return NULL; 142 146 } else if (opt == 'u') { … … 162 166 they're secure when in fact they're not. */ 163 167 fprintf(stderr, "Error: Could not read CA file %s: %s\n", conf->cafile, strerror(errno)); 168 conf_free(conf); 164 169 return NULL; 165 170 } 166 171 167 172 return conf; 173 } 174 175 static void conf_free(conf_t *conf) 176 { 177 /* Free software means users have the four essential freedoms: 178 0. to run the program, 179 2. to study and change the program in source code form, 180 2. to redistribute exact copies, and 181 3. to distribute modified versions 182 */ 183 g_free(conf->auth_pass); 184 g_free(conf->cafile); 185 g_free(conf->configdir); 186 g_free(conf->ft_listen); 187 g_free(conf->hostname); 188 g_free(conf->iface_in); 189 g_free(conf->iface_out); 190 g_free(conf->motdfile); 191 g_free(conf->oper_pass); 192 g_free(conf->pidfile); 193 g_free(conf->plugindir); 194 g_free(conf->port); 195 g_free(conf->primary_storage); 196 g_free(conf->user); 197 g_strfreev(conf->migrate_storage); 198 g_strfreev(conf->protocols); 199 g_free(conf); 200 168 201 } 169 202 … … 219 252 g_free(conf->configdir); 220 253 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); 221 257 } else if (g_strcasecmp(ini->key, "motdfile") == 0) { 222 258 g_free(conf->motdfile); … … 259 295 } else if (url->proto == PROTO_SOCKS5) { 260 296 proxytype = PROXY_SOCKS5; 297 } else if (url->proto == PROTO_SOCKS4A) { 298 proxytype = PROXY_SOCKS4A; 261 299 } 262 300 -
configure
re4f08bf r29ff5c2 23 23 pcdir='$prefix/lib/pkgconfig' 24 24 systemlibdirs="/lib64 /usr/lib64 /usr/local/lib64 /lib /usr/lib /usr/local/lib" 25 sysroot='' 25 26 26 27 # Set these to default-on to let it be overriden by either the user or purple … … 51 52 pie=1 52 53 53 arch= `uname -s`54 cpu= `uname -m`54 arch=$(uname -s) 55 cpu=$(uname -m) 55 56 56 57 GLIB_MIN_VERSION=2.16 … … 103 104 104 105 while [ -n "$1" ]; do 105 e=" `expr "X$1" : 'X--\(.*=.*\)'`"106 e="$(expr "X$1" : 'X--\(.*=.*\)')" 106 107 if [ -z "$e" ]; then 107 108 cat<<EOF … … 149 150 150 151 --target=... Cross compilation target same as host 152 --sysroot=... Cross compilation sysroot $sysroot 151 153 EOF 152 154 exit; … … 157 159 158 160 # Expand $prefix and get rid of double slashes 159 bindir= `eval echo "$bindir/" | sed 's/\/\{1,\}/\//g'`160 sbindir= `eval echo "$sbindir/" | sed 's/\/\{1,\}/\//g'`161 etcdir= `eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g'`162 mandir= `eval echo "$mandir/" | sed 's/\/\{1,\}/\//g'`163 datadir= `eval echo "$datadir/" | sed 's/\/\{1,\}/\//g'`164 config= `eval echo "$config/" | sed 's/\/\{1,\}/\//g'`165 plugindir= `eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'`166 includedir= `eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g'`167 libevent= `eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g'`168 169 pidfile= `eval echo "$pidfile" | sed 's/\/\{1,\}/\//g'`170 ipcsocket= `eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g'`171 pcdir= `eval echo "$pcdir" | sed 's/\/\{1,\}/\//g'`161 bindir=$(eval echo "$bindir/" | sed 's/\/\{1,\}/\//g') 162 sbindir=$(eval echo "$sbindir/" | sed 's/\/\{1,\}/\//g') 163 etcdir=$(eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g') 164 mandir=$(eval echo "$mandir/" | sed 's/\/\{1,\}/\//g') 165 datadir=$(eval echo "$datadir/" | sed 's/\/\{1,\}/\//g') 166 config=$(eval echo "$config/" | sed 's/\/\{1,\}/\//g') 167 plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g') 168 includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g') 169 libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g') 170 171 pidfile=$(eval echo "$pidfile" | sed 's/\/\{1,\}/\//g') 172 ipcsocket=$(eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g') 173 pcdir=$(eval echo "$pcdir" | sed 's/\/\{1,\}/\//g') 172 174 173 175 protocols_mods="" … … 240 242 241 243 if [ -n "$target" ]; then 242 PKG_CONFIG_LIBDIR=/usr/$target/lib/pkgconfig 243 export PKG_CONFIG_LIBDIR 244 PATH=/usr/$target/bin:$PATH 244 # prepend sysroot to system lib dirs 245 246 systemlibdirs_cross='' 247 for i in $systemlibdirs; do 248 systemlibdirs_cross="$systemlibdirs_cross $sysroot$i" 249 done 250 systemlibdirs=$systemlibdirs_cross 251 unset systemlibdirs_cross 252 253 # backward compatibility 254 255 if [ -z "$PKG_CONFIG_LIBDIR" ]; then 256 PKG_CONFIG_LIBDIR=/usr/$target/lib/pkgconfig 257 export PKG_CONFIG_LIBDIR 258 fi 259 260 if [ -d /usr/$target/bin ]; then 261 PATH=/usr/$target/bin:$PATH 262 fi 263 264 if [ -d /usr/$target/lib ]; then 265 systemlibdirs="$systemlibdirs /usr/$target/lib" 266 fi 267 245 268 CC=$target-cc 246 269 LD=$target-ld 247 systemlibdirs="/usr/$target/lib"270 STRIP=$target-strip 248 271 fi 249 272 … … 308 331 if $PKG_CONFIG glib-2.0 --atleast-version=$GLIB_MIN_VERSION; then 309 332 cat<<EOF >>Makefile.settings 310 EFLAGS+= `$PKG_CONFIG --libs glib-2.0 gmodule-2.0`311 CFLAGS+= `$PKG_CONFIG --cflags glib-2.0 gmodule-2.0`333 EFLAGS+=$($PKG_CONFIG --libs glib-2.0 gmodule-2.0) 334 CFLAGS+=$($PKG_CONFIG --cflags glib-2.0 gmodule-2.0) 312 335 EOF 313 336 else 314 337 echo 315 echo 'Found glib2 ' `$PKG_CONFIG glib-2.0 --modversion`', but version '$GLIB_MIN_VERSION' or newer is required.'338 echo 'Found glib2 '$($PKG_CONFIG glib-2.0 --modversion)', but version '$GLIB_MIN_VERSION' or newer is required.' 316 339 exit 1 317 340 fi … … 349 372 if $PKG_CONFIG --exists gnutls; then 350 373 cat <<EOF >>Makefile.settings 351 EFLAGS+= `$PKG_CONFIG --libs gnutls` `libgcrypt-config --libs`352 CFLAGS+= `$PKG_CONFIG --cflags gnutls` `libgcrypt-config --cflags`374 EFLAGS+=$($PKG_CONFIG --libs gnutls) $(libgcrypt-config --libs) 375 CFLAGS+=$($PKG_CONFIG --cflags gnutls) $(libgcrypt-config --cflags) 353 376 EOF 354 377 ssl=gnutls 355 if ! pkg-configgnutls --atleast-version=2.8; then378 if ! $PKG_CONFIG gnutls --atleast-version=2.8; then 356 379 echo 357 380 echo 'Warning: With GnuTLS versions <2.8, certificate expire dates are not verified.' … … 360 383 elif libgnutls-config --version > /dev/null 2> /dev/null; then 361 384 cat <<EOF >>Makefile.settings 362 EFLAGS+= `libgnutls-config --libs` `libgcrypt-config --libs`363 CFLAGS+= `libgnutls-config --cflags` `libgcrypt-config --cflags`385 EFLAGS+=$(libgnutls-config --libs) $(libgcrypt-config --libs) 386 CFLAGS+=$(libgnutls-config --cflags) $(libgcrypt-config --cflags) 364 387 EOF 365 388 … … 375 398 if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG nss; then 376 399 cat<<EOF >>Makefile.settings 377 EFLAGS+= `$PKG_CONFIG --libs nss`378 CFLAGS+= `$PKG_CONFIG --cflags nss`400 EFLAGS+=$($PKG_CONFIG --libs nss) 401 CFLAGS+=$($PKG_CONFIG --cflags nss) 379 402 EOF 380 403 … … 621 644 if [ -z "$systemdsystemunitdir" ]; then 622 645 if $PKG_CONFIG --exists systemd; then 623 systemdsystemunitdir= `$PKG_CONFIG --variable=systemdsystemunitdir systemd`646 systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd) 624 647 fi 625 648 fi … … 643 666 644 667 otrprefix="" 645 for i in / /usr /usr/local; do646 if [ -f ${i}/lib/libotr.a ]; then647 otrprefix=${i}648 break649 fi650 done651 668 if [ "$otr" = "auto" ]; then 652 if [ -n "$otrprefix" ]; then 653 otr=1 654 else 655 otr=0 656 fi 657 fi 669 ! $PKG_CONFIG --exists libotr 670 otr=$? 671 fi 672 673 if [ "$otr" != 0 ] && ! $PKG_CONFIG --atleast-version=4.0 --print-errors libotr; then 674 exit 1 675 fi 676 658 677 if [ "$otr" = 1 ]; then 659 678 # BI == built-in 660 679 echo '#define OTR_BI' >> config.h 661 echo "EFLAGS+= -L${otrprefix}/lib -lotr -lgcrypt" >> Makefile.settings662 echo "CFLAGS+= -I${otrprefix}/include" >> Makefile.settings680 echo "EFLAGS+=$($PKG_CONFIG --libs libotr) $(libgcrypt-config --libs)" >> Makefile.settings 681 echo "CFLAGS+=$($PKG_CONFIG --cflags libotr) $(libgcrypt-config --cflags)" >> Makefile.settings 663 682 echo 'OTR_BI=otr.o' >> Makefile.settings 664 683 elif [ "$otr" = "plugin" ]; then 684 # for some mysterious reason beyond the comprehension of my mortal mind, 685 # the libgcrypt flags aren't needed when building as plugin. add them anyway. 665 686 echo '#define OTR_PI' >> config.h 666 echo "OTRFLAGS= -L${otrprefix}/lib -lotr" >> Makefile.settings667 echo "CFLAGS+= -I${otrprefix}/include" >> Makefile.settings687 echo "OTRFLAGS=$($PKG_CONFIG --libs libotr) $(libgcrypt-config --libs)" >> Makefile.settings 688 echo "CFLAGS+=$($PKG_CONFIG --cflags libotr) $(libgcrypt-config --cflags)" >> Makefile.settings 668 689 echo 'OTR_PI=otr.so' >> Makefile.settings 669 fi670 if [ "$otr" != 0 ] && ! pkg-config libotr --atleast-version=4.0; then671 echo672 echo 'WARNING: Your libotr seems to be old. BitlBee now needs at least libotr 4.0.'673 # Not hard-failing because the code above doesn't use pkg-config, so who knows674 # what's true at this point...675 690 fi 676 691 -
dcc.c
re4f08bf r29ff5c2 265 265 } 266 266 267 /* How likely is it that a 32-bit integer gets split ac cross267 /* How likely is it that a 32-bit integer gets split across 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
re4f08bf r29ff5c2 1 bitlbee (3. 2.2-2) UNRELEASED; urgency=medium1 bitlbee (3.4.1-1) unstable; urgency=medium 2 2 3 3 * Fix copyright info (Closes: #764181) 4 5 -- Wilmer van der Gaast <wilmer@gaast.net> Fri, 17 Oct 2014 23:25:33 +0100 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 6 8 7 9 bitlbee (3.2.2-1) unstable; urgency=medium -
debian/source/options
re4f08bf r29ff5c2 1 --diff-ignore='(^|/)\. bzr'1 --diff-ignore='(^|/)\.git' -
doc/CHANGES
re4f08bf r29ff5c2 3 3 4 4 https://github.com/bitlbee/bitlbee/commits/master 5 6 Version 3.4.1: 7 - msn: 8 * Upgraded protocol to MSNP21, works again (dx) 9 * Contact list management, groupchats and skype username logins won't work. 10 Next release! 11 - jabber: 12 * Add "hipchat" protocol, for smoother login. Takes the same username as 13 the official client. Note that unlike the 'hip-cat' branch, this doesn't 14 preload channels. https://wiki.bitlbee.org/HowtoHipchat for details (dx) 15 * Fixed a bug when receiving topics set by people who left the channel (dx) 16 * Create fake users instead of showing "unknown participant" errors (dx) 17 * Gmail mail notifications support (Artem Savkov) 18 * Lowering xmpp presence priority on away (Artem Savkov) 19 - twitter: 20 * Show quoted tweets/RTs with comment inline (wilmer) 21 * Added "url" command, can be used to quote tweets (wilmer) 22 * Make replies to self work (wilmer) 23 - Building documentation is now done with a python script (both 2.x/3.x work) 24 Asciidoc/xsltproc/xmlto are no longer build dependencies (dx) 25 26 Finished 16 Jun 2015 5 27 6 28 Version 3.4: … … 407 429 officially be treated as case sensitive. 408 430 - Fully stripping spaces from AIM screennames, this didn't happen completely 409 which sever ly breaks the IRC protocol.431 which severely breaks the IRC protocol. 410 432 - Removed all the yellow tape around daemon mode, it's pretty mature by now: 411 433 testing.bitlbee.org serves all (~30) SSL users from one daemon mode … … 607 629 some situations. 608 630 - Outgoing MSN typing notifications are now understood correctly by the 609 orig nal MS Mac/Windows clients (again).631 original MS Mac/Windows clients (again). 610 632 - Added "account add $protocol" to the documentation, got rid of a lot 611 633 of over-markup (i.e. overuse of bold-tags), reviewed some other parts. -
doc/HACKING
re4f08bf r29ff5c2 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 cross16 However, up to late in the 1.2 series, the IRC core was still spread across 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
re4f08bf r29ff5c2 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 MODES 12 ========= 10 13 11 14 --- (Fork)Daemon mode … … 89 92 ================== 90 93 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) 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) 105 98 106 99 If someone can tell us how to write Makefiles that work with both/all … … 153 146 ============================= 154 147 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. 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. 160 151 161 152 However, once you log into the BitlBee server and send your password, an 162 153 intruder with tcpdump can still read your passwords. This can't really be 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 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. 177 156 178 157 LEGAL … … 181 160 BitlBee is distributed under the GPL (GNU General Public License). See the 182 161 file COPYING for this license. 183 184 The MD5 algorithm code is licensed under the Aladdin license. This license185 can be found in the files, to which this applies. The SHA1 algorithm code186 is licensed under the Mozilla Public License, see http://www.mozilla.org/MPL/187 for details.188 162 189 163 The Yahoo! library used by BitlBee is libyahoo2 <http://libyahoo2.sf.net/>, -
doc/user-guide/Installation.xml
re4f08bf r29ff5c2 73 73 <para> 74 74 By default, BitlBee runs as the user nobody. You might want 75 to run it as a sep erate user (some computers run named or apache as nobody).75 to run it as a separate user (some computers run named or apache as nobody). 76 76 </para> 77 77 -
doc/user-guide/commands.xml
re4f08bf r29ff5c2 182 182 183 183 <para> 184 For more info mation about a setting, see <emphasis>help set <setting></emphasis>.184 For more information about a setting, see <emphasis>help set <setting></emphasis>. 185 185 </para> 186 186 … … 240 240 241 241 <para> 242 For more info mation about a setting, see <emphasis>help set <setting></emphasis>.242 For more information about a setting, see <emphasis>help set <setting></emphasis>. 243 243 </para> 244 244 … … 1093 1093 1094 1094 <para> 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.1095 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). 1096 1096 </para> 1097 1097 … … 1186 1186 </bitlbee-setting> 1187 1187 1188 <bitlbee-setting name="anonymous" type="boolean" scope="account"> 1189 <default>false</default> 1190 1191 <description> 1192 <para> 1193 This enables SASL ANONYMOUS login for jabber accounts, as specified by XEP-0175. 1194 </para> 1195 1196 <para> 1197 With this setting enabled, if the server allows this method, a password isn't required and the username part of the JID is ignored (you can use anonymous@jabber.example.com). Servers will usually assign you a random numeric username instead. 1198 </para> 1199 </description> 1200 1201 </bitlbee-setting> 1202 1188 1203 <bitlbee-setting name="ops" type="string" scope="global"> 1189 1204 <default>both</default> … … 1309 1324 </bitlbee-setting> 1310 1325 1326 <bitlbee-setting name="proxy" type="string" scope="account"> 1327 <default><local><auto></default> 1328 1329 <description> 1330 <para> 1331 A list of <emphasis>file transfer proxies</emphasis> for jabber. This isn't the connection proxy. Sorry, look in bitlbee.conf for those. 1332 </para> 1333 1334 <para> 1335 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". 1336 </para> 1337 <para> 1338 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. 1339 </para> 1340 <para> 1341 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. 1342 </para> 1343 </description> 1344 </bitlbee-setting> 1345 1311 1346 <bitlbee-setting name="query_order" type="string" scope="global"> 1312 1347 <default>lifo</default> … … 1369 1404 </bitlbee-setting> 1370 1405 1406 <bitlbee-setting name="self_messages" type="string" scope="global"> 1407 <default>true</default> 1408 <possible-values>true, false, prefix, prefix_notice</possible-values> 1409 1410 <description> 1411 <para> 1412 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. 1413 </para> 1414 1415 <para> 1416 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. 1417 </para> 1418 1419 <para> 1420 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. 1421 </para> 1422 1423 <para> 1424 You can also set it to "false" to disable these messages completely. 1425 </para> 1426 1427 <para> 1428 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. 1429 </para> 1430 </description> 1431 </bitlbee-setting> 1432 1371 1433 <bitlbee-setting name="server" type="string" scope="account"> 1372 1434 <description> … … 1402 1464 1403 1465 <bitlbee-setting name="show_users" type="string" scope="channel"> 1404 <default>online+, away</default>1466 <default>online+,special%,away</default> 1405 1467 1406 1468 <description> … … 1409 1471 and any modes they should have. The following statuses are currently 1410 1472 recognised: <emphasis>online</emphasis> (i.e. available, not 1411 away), <emphasis>away</emphasis>, and <emphasis>offline</emphasis>. 1473 away), <emphasis>special</emphasis>, <emphasis>away</emphasis>, 1474 and <emphasis>offline</emphasis>. 1412 1475 </para> 1413 1476 … … 1415 1478 If a status is followed by a valid channel mode character 1416 1479 (@, % or +), it will be given to users with that status. 1417 For example, <emphasis>online@, away+,offline</emphasis> will1418 show all users in the channel. Online people will1480 For example, <emphasis>online@,special%,away+,offline</emphasis> 1481 will show all users in the channel. Online people will 1419 1482 have +o, people who are online but away will have +v, 1420 1483 and others will have no special modes. … … 1876 1939 1877 1940 <description> 1878 <para>Rejects all incoming (not already transferring) file transfers. Since you probably have only one incoming transfer at a time, no id is nec cessary. Or is it?</para>1941 <para>Rejects all incoming (not already transferring) file transfers. Since you probably have only one incoming transfer at a time, no id is necessary. Or is it?</para> 1879 1942 </description> 1880 1943 -
doc/user-guide/misc.xml
re4f08bf r29ff5c2 90 90 91 91 <para> 92 Away states have different names ac cross different protocols. BitlBee will try to pick the best available option for every connection:92 Away states have different names across 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 cross 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 across several channels. 149 149 </para> 150 150 … … 433 433 </sect1> 434 434 435 <sect1 id="whatsnew030401"> 436 <title>New stuff in BitlBee 3.4.1</title> 437 438 <simplelist> 439 <member><emphasis>msn:</emphasis> Upgraded protocol version to MSNP21, works again</member> 440 <member><emphasis>jabber:</emphasis> Add "hipchat" protocol, for smoother login. Takes the same username as the official client. Note that unlike the 'hip-cat' branch, this doesn't preload channels. See the <emphasis>HowtoHipchat</emphasis> wiki page for details</member> 441 <member><emphasis>jabber:</emphasis> Gmail notifications support</member> 442 <member><emphasis>twitter:</emphasis> Show quoted tweets inline. Added "url" command, can be used to quote tweets.</member> 443 </simplelist> 444 445 </sect1> 446 435 447 </chapter> -
doc/user-guide/quickstart.xml
re4f08bf r29ff5c2 11 11 12 12 <para> 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!).13 You need to register so that all your IM settings (passwords, contacts, etc) can be saved on the BitlBee server. It's important that you pick a good password so no one else can access your account. Register with this password using the <emphasis>register</emphasis> command: <emphasis>register <password></emphasis> (without the brackets!). 14 14 </para> 15 15 -
help.c
re4f08bf r29ff5c2 146 146 if (lseek(h->fd, h->offset.file_offset, SEEK_SET) == -1 || 147 147 read(h->fd, s, h->length) != h->length) { 148 g_free(s); 148 149 return NULL; 149 150 } -
ipc.c
re4f08bf r29ff5c2 590 590 } 591 591 592 *recv_fd = *(int *) CMSG_DATA(cmsg);592 memcpy(recv_fd, CMSG_DATA(cmsg), sizeof(int)); 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 *(int *) CMSG_DATA(cmsg) = send_fd;760 memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(int)); 761 761 msg.msg_controllen = cmsg->cmsg_len; 762 762 #endif -
irc.c
re4f08bf r29ff5c2 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); 131 132 s = set_add(&b->set, "simulate_netsplit", "true", set_eval_bool, irc); 132 133 s = set_add(&b->set, "timezone", "local", set_eval_timezone, irc); … … 153 154 set_eval_charset(set_find(&b->set, "charset"), set_getstr(&b->set, "charset")); 154 155 155 irc_write(irc, ":%s NOTICE AUTH:%s", irc->root->host, "BitlBee-IRCd initialized, please go on");156 irc_write(irc, ":%s NOTICE * :%s", irc->root->host, "BitlBee-IRCd initialized, please go on"); 156 157 if (isatty(irc->fd)) { 157 irc_write(irc, ":%s NOTICE AUTH:%s", irc->root->host,158 irc_write(irc, ":%s NOTICE * :%s", irc->root->host, 158 159 "If you read this, you most likely accidentally " 159 160 "started BitlBee in inetd mode on the command line. " … … 380 381 conv = NULL; 381 382 } else { 382 irc_write(irc, ":%s NOTICE AUTH:%s", irc->root->host,383 irc_write(irc, ":%s NOTICE * :%s", irc->root->host, 383 384 "Warning: invalid characters received at login time."); 384 385 … … 727 728 int irc_check_login(irc_t *irc) 728 729 { 729 if (irc->user->user && irc->user->nick ) {730 if (irc->user->user && irc->user->nick && !(irc->status & USTATUS_CAP_PENDING)) { 730 731 if (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED)) { 731 732 irc_send_num(irc, 464, ":This server is password-protected."); -
irc.h
re4f08bf r29ff5c2 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, 51 53 52 54 /* Not really status stuff, but other kinds of flags: For slightly … … 65 67 } irc_status_t; 66 68 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 } irc_cap_flag_t; 75 67 76 struct irc_user; 68 77 … … 102 111 103 112 struct bee *b; 113 guint32 caps; 104 114 } irc_t; 105 115 … … 305 315 gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name); 306 316 void irc_channel_update_ops(irc_channel_t *ic, char *value); 317 char irc_channel_user_get_prefix(irc_channel_user_t *icu); 307 318 char *set_eval_irc_channel_ops(struct set *set, char *value); 308 319 gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu); … … 334 345 irc_channel_user_flags_t old_flags, irc_channel_user_flags_t new_flags); 335 346 void irc_send_invite(irc_user_t *iu, irc_channel_t *ic); 347 void irc_send_cap(irc_t *irc, char *subcommand, char *body); 348 void irc_send_away_notify(irc_user_t *iu); 336 349 337 350 /* irc_user.c */ … … 347 360 char *set_eval_timezone(struct set *set, char *value); 348 361 char *irc_format_timestamp(irc_t *irc, time_t msg_ts); 362 char *set_eval_self_messages(struct set *set, char *value); 349 363 350 364 /* irc_im.c */ … … 352 366 void bee_irc_user_nick_reset(irc_user_t *iu); 353 367 368 /* irc_cap.c */ 369 void irc_cmd_cap(irc_t *irc, char **cmd); 370 354 371 #endif -
irc_channel.c
re4f08bf r29ff5c2 429 429 } 430 430 431 char irc_channel_user_get_prefix(irc_channel_user_t *icu) 432 { 433 if (icu->flags & IRC_CHANNEL_USER_OP) { 434 return '@'; 435 } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) { 436 return '%'; 437 } else if (icu->flags & IRC_CHANNEL_USER_VOICE) { 438 return '+'; 439 } 440 return 0; 441 } 442 431 443 void irc_channel_auto_joins(irc_t *irc, account_t *acc) 432 444 { … … 445 457 char *acc_s; 446 458 447 if (!aj ||(ic->flags & IRC_CHANNEL_JOINED)) {448 /* Only continueif this one's marked as auto_join449 or if we're in it already. ( Possible if the450 client auto- rejoined it before identyfing.) */459 if (!aj && !(ic->flags & IRC_CHANNEL_JOINED)) { 460 /* Only proceed if this one's marked as auto_join 461 or if we're in it already. (Very likely the IRC 462 client auto-(re)joining at reconnect time.) */ 451 463 continue; 452 464 } else if (!(acc_s = set_getstr(&ic->set, "account"))) { … … 593 605 594 606 translit_name = g_convert_with_fallback(hint, -1, "ASCII//TRANSLIT", "UTF-8", "", NULL, &bytes_written, NULL); 607 608 if (!translit_name) { 609 /* Same thing as in nick_gen() in nick.c, try again without //TRANSLIT */ 610 translit_name = g_convert_with_fallback(hint, -1, "ASCII", "UTF-8", "", NULL, &bytes_written, NULL); 611 } 612 613 if (!translit_name) { 614 return NULL; 615 } 616 595 617 if (bytes_written > MAX_NICK_LENGTH) { 596 618 translit_name[MAX_NICK_LENGTH] = '\0'; -
irc_commands.c
re4f08bf r29ff5c2 28 28 #include "help.h" 29 29 #include "ipc.h" 30 #include "base64.h" 30 31 31 32 static void irc_cmd_pass(irc_t *irc, char **cmd) … … 55 56 irc_setpass(irc, cmd[1]); 56 57 irc_check_login(irc); 58 } 59 } 60 61 static gboolean irc_sasl_plain_parse(char *input, char **user, char **pass) 62 { 63 int i, part, len; 64 guint8 *decoded; 65 char *parts[3]; 66 67 /* bitlbee's base64_decode wrapper adds an extra null terminator at the end */ 68 len = base64_decode(input, &decoded); 69 70 /* this loop splits the decoded string into the parts array, like this: 71 "username\0username\0password" -> {"username", "username", "password"} */ 72 73 for (i = 0, part = 0; i < len && part < 3; part++) { 74 /* set each of parts[] to point to the beginning of a string */ 75 parts[part] = (char *) decoded + i; 76 77 /* move the cursor forward to the next null terminator*/ 78 i += strlen(parts[part]) + 1; 79 } 80 81 /* sanity checks */ 82 if (part != 3 || i != (len + 1) || (parts[0][0] && strcmp(parts[0], parts[1]) != 0)) { 83 g_free(decoded); 84 return FALSE; 85 } else { 86 *user = g_strdup(parts[1]); 87 *pass = g_strdup(parts[2]); 88 g_free(decoded); 89 return TRUE; 90 } 91 } 92 93 static gboolean irc_sasl_check_pass(irc_t *irc, char *user, char *pass) 94 { 95 storage_status_t status; 96 97 /* just check the password here to be able to reply with useful numerics 98 * the actual identification will be handled later */ 99 status = storage_check_pass(user, pass); 100 101 if (status == STORAGE_OK) { 102 if (!irc->user->nick) { 103 /* set the nick here so we have it for the following numeric */ 104 irc->user->nick = g_strdup(user); 105 } 106 irc_send_num(irc, 903, ":Password accepted"); 107 return TRUE; 108 109 } else if (status == STORAGE_INVALID_PASSWORD) { 110 irc_send_num(irc, 904, ":Incorrect password"); 111 } else if (status == STORAGE_NO_SUCH_USER) { 112 irc_send_num(irc, 904, ":The nick is (probably) not registered"); 113 } else { 114 irc_send_num(irc, 904, ":Unknown SASL authentication error"); 115 } 116 117 return FALSE; 118 } 119 120 static void irc_cmd_authenticate(irc_t *irc, char **cmd) 121 { 122 /* require the CAP to be enabled, and don't allow authentication before server password */ 123 if (!(irc->caps & CAP_SASL) || 124 (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED))) { 125 return; 126 } 127 128 if (irc->status & USTATUS_SASL_PLAIN_PENDING) { 129 char *user, *pass; 130 131 irc->status &= ~USTATUS_SASL_PLAIN_PENDING; 132 133 if (!irc_sasl_plain_parse(cmd[1], &user, &pass)) { 134 irc_send_num(irc, 904, ":SASL authentication failed"); 135 return; 136 } 137 138 /* let's not support the nick != user case 139 * if NICK is received after SASL, it will just fail after registration */ 140 if (user && irc->user->nick && strcmp(user, irc->user->nick) != 0) { 141 irc_send_num(irc, 902, ":Your SASL username does not match your nickname"); 142 143 } else if (irc_sasl_check_pass(irc, user, pass)) { 144 /* and here we do the same thing as the PASS command*/ 145 if (irc->status & USTATUS_LOGGED_IN) { 146 char *send_cmd[] = { "identify", pass, NULL }; 147 root_command(irc, send_cmd); 148 } else { 149 /* no check_login here - wait for CAP END */ 150 irc_setpass(irc, pass); 151 } 152 } 153 154 g_free(user); 155 g_free(pass); 156 157 } else if (irc->status & USTATUS_IDENTIFIED) { 158 irc_send_num(irc, 907, ":You have already authenticated"); 159 160 } else if (strcmp(cmd[1], "*") == 0) { 161 irc_send_num(irc, 906, ":SASL authentication aborted"); 162 irc->status &= ~USTATUS_SASL_PLAIN_PENDING; 163 164 } else if (g_strcasecmp(cmd[1], "PLAIN") == 0) { 165 irc_write(irc, "AUTHENTICATE +"); 166 irc->status |= USTATUS_SASL_PLAIN_PENDING; 167 168 } else { 169 irc_send_num(irc, 908, "PLAIN :is the available SASL mechanism"); 170 irc_send_num(irc, 904, ":SASL authentication failed"); 171 irc->status &= ~USTATUS_SASL_PLAIN_PENDING; 57 172 } 58 173 } … … 83 198 irc->status &= ~USTATUS_IDENTIFIED; 84 199 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 85 206 irc_rootmsg(irc, "Changing nicks resets your identify status. " 86 207 "Re-identify or register a new account if you want " … … 685 806 686 807 static const command_t irc_commands[] = { 808 { "cap", 1, irc_cmd_cap, 0 }, 687 809 { "pass", 1, irc_cmd_pass, 0 }, 688 810 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, … … 721 843 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 722 844 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 845 { "authenticate", 1, irc_cmd_authenticate, 0 }, 723 846 { NULL } 724 847 }; -
irc_im.c
re4f08bf r29ff5c2 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); 120 126 } 121 127 … … 201 207 } 202 208 203 static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at)209 static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, guint32 flags, time_t sent_at) 204 210 { 205 211 irc_t *irc = bee->ui_data; 206 212 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; 207 215 const char *dst; 208 216 char *prefix = NULL; 209 217 char *wrapped, *ts = NULL; 210 218 char *msg = g_strdup(msg_); 219 char *message_type = "PRIVMSG"; 211 220 GSList *l; 212 221 … … 216 225 217 226 dst = irc_user_msgdest(iu); 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 ? : ""); 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 ? : ""); 221 265 } else { 222 266 prefix = ts; … … 249 293 250 294 wrapped = word_wrap(msg, 425); 251 irc_send_msg( iu, "PRIVMSG", dst, wrapped, prefix);295 irc_send_msg(src_iu, message_type, dst, wrapped, prefix); 252 296 g_free(wrapped); 253 297 … … 260 304 } 261 305 262 static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, uint32_tflags)306 static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, guint32 flags) 263 307 { 264 308 irc_t *irc = (irc_t *) bee->ui_data; … … 646 690 } 647 691 648 static gboolean bee_irc_chat_msg(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at)692 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) 649 693 { 650 694 irc_t *irc = bee->ui_data; 651 irc_user_t *iu = bu->ui_data;695 irc_user_t *iu = flags & OPT_SELFMESSAGE ? irc->user : bu->ui_data; 652 696 irc_channel_t *ic = c->ui_data; 653 697 char *wrapped, *ts = NULL; … … 683 727 } 684 728 685 static gboolean bee_irc_chat_remove_user(bee_t *bee, struct groupchat *c, bee_user_t *bu )729 static gboolean bee_irc_chat_remove_user(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *reason) 686 730 { 687 731 irc_t *irc = bee->ui_data; … … 695 739 using imcb_chat_free() and the channel was IRC_CHANNEL_TEMP, we get into 696 740 a broken state around here. */ 697 irc_channel_del_user(ic, bu == bee->user ? irc->user : bu->ui_data, IRC_CDU_PART, NULL);741 irc_channel_del_user(ic, bu == bee->user ? irc->user : bu->ui_data, IRC_CDU_PART, reason); 698 742 699 743 return TRUE; … … 867 911 (room = set_getstr(&ic->set, "room")) && 868 912 (acc = account_get(ic->irc->b, acc_s)) && 869 acc->ic && acc->prpl->chat_join) { 913 acc->ic && (acc->ic->flags & OPT_LOGGED_IN) && 914 acc->prpl->chat_join) { 870 915 char *nick; 871 916 … … 893 938 } 894 939 895 /* Remove the reference. We don't need it anymore. */ 896 ic->data = NULL; 940 if (!(ic->flags & IRC_CHANNEL_TEMP)) { 941 /* Remove the reference. 942 * We only need it for temp channels that are being freed */ 943 ic->data = NULL; 944 } 897 945 898 946 return TRUE; -
irc_send.c
re4f08bf r29ff5c2 172 172 irc_t *irc = ic->irc; 173 173 174 irc_write(irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name); 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 } 175 179 176 180 if (iu == irc->user) { … … 214 218 } 215 219 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 } 220 namelist[strlen(namelist) + 1] = '\0'; 221 namelist[strlen(namelist)] = irc_channel_user_get_prefix(icu); 223 222 224 223 strcat(namelist, iu->nick); … … 249 248 } 250 249 250 /* msg1 and msg2 are output parameters. If msg2 is non-null, msg1 is guaranteed to be non-null too. 251 The idea is to defer the formatting of "$msg1 ($msg2)" to later calls to avoid a g_strdup_printf() here. */ 252 static void get_status_message(bee_user_t *bu, char **msg1, char **msg2) 253 { 254 *msg1 = NULL; 255 *msg2 = NULL; 256 257 if (!(bu->flags & BEE_USER_ONLINE)) { 258 *msg1 = "User is offline"; 259 260 } else if ((bu->status && *bu->status) || 261 (bu->status_msg && *bu->status_msg)) { 262 263 if (bu->status && bu->status_msg) { 264 *msg1 = bu->status; 265 *msg2 = bu->status_msg; 266 } else { 267 *msg1 = bu->status ? : bu->status_msg; 268 } 269 } 270 271 if (*msg1 && !**msg1) { 272 *msg1 = (bu->flags & BEE_USER_AWAY) ? "Away" : NULL; 273 } 274 } 275 251 276 void irc_send_whois(irc_user_t *iu) 252 277 { … … 258 283 if (iu->bu) { 259 284 bee_user_t *bu = iu->bu; 285 char *msg1, *msg2; 286 int num; 260 287 261 288 irc_send_num(irc, 312, "%s %s.%s :%s network", iu->nick, bu->ic->acc->user, … … 263 290 bu->ic->acc->prpl->name); 264 291 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"); 292 num = (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) ? 301 : 320; 293 294 get_status_message(bu, &msg1, &msg2); 295 296 if (msg1 && msg2) { 297 irc_send_num(irc, num, "%s :%s (%s)", iu->nick, msg1, msg2); 298 } else if (msg1) { 299 irc_send_num(irc, num, "%s :%s", iu->nick, msg1); 276 300 } 277 301 … … 294 318 295 319 while (l) { 296 irc_user_t *iu = l->data; 320 irc_user_t *iu; 321 322 /* Null terminated string with three chars, respectively: 323 * { <H|G>, <@|%|+|\0>, \0 } */ 324 char status_prefix[3] = {0}; 325 297 326 if (is_channel) { 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", 327 irc_channel_user_t *icu = l->data; 328 status_prefix[1] = irc_channel_user_get_prefix(icu); 329 iu = icu->iu; 330 } else { 331 iu = l->data; 332 } 333 334 /* rfc1459 doesn't mention this: G means gone, H means here */ 335 status_prefix[0] = iu->flags & IRC_USER_AWAY ? 'G' : 'H'; 336 337 irc_send_num(irc, 352, "%s %s %s %s %s %s :0 %s", 302 338 is_channel ? channel : "*", iu->user, iu->host, irc->root->host, 303 iu->nick, iu->flags & IRC_USER_AWAY ? 'G' : 'H', 304 iu->fullname); 339 iu->nick, status_prefix, iu->fullname); 305 340 l = l->next; 306 341 } … … 428 463 iu->nick, iu->user, iu->host, irc->user->nick, ic->name); 429 464 } 465 466 void irc_send_cap(irc_t *irc, char *subcommand, char *body) 467 { 468 char *nick = irc->user->nick ? : "*"; 469 470 irc_write(irc, ":%s CAP %s %s :%s", irc->root->host, nick, subcommand, body); 471 } 472 473 void irc_send_away_notify(irc_user_t *iu) 474 { 475 bee_user_t *bu = iu->bu; 476 477 if (!bu) { 478 return; 479 } 480 481 if (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) { 482 char *msg1, *msg2; 483 484 get_status_message(bu, &msg1, &msg2); 485 486 if (msg2) { 487 irc_write(iu->irc, ":%s!%s@%s AWAY :%s (%s)", iu->nick, iu->user, iu->host, msg1, msg2); 488 } else { 489 irc_write(iu->irc, ":%s!%s@%s AWAY :%s", iu->nick, iu->user, iu->host, msg1); 490 } 491 } else { 492 irc_write(iu->irc, ":%s!%s@%s AWAY", iu->nick, iu->user, iu->host); 493 } 494 } 495 -
irc_util.c
re4f08bf r29ff5c2 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
re4f08bf r29ff5c2 162 162 } 163 163 164 req->func(req); 164 if (req->func != NULL) { 165 req->func(req); 166 } 165 167 http_free(req); 166 168 return FALSE; … … 299 301 } 300 302 301 req->func(req); 303 if (req->func != NULL) { 304 req->func(req); 305 } 302 306 http_free(req); 303 307 return FALSE; … … 412 416 } 413 417 414 if ((req->flags & HTTPC_STREAMING) && req->reply_body ) {418 if ((req->flags & HTTPC_STREAMING) && req->reply_body && req->func != NULL) { 415 419 req->func(req); 416 420 } … … 696 700 ssl_disconnect(req->ssl); 697 701 } else { 698 closesocket(req->fd);702 proxy_disconnect(req->fd); 699 703 } 700 704 -
lib/json.c
re4f08bf r29ff5c2 509 509 case ']': 510 510 511 if (top ->type == json_array) {511 if (top && top->type == json_array) { 512 512 flags = (flags & ~(flag_need_comma | flag_seek_value)) | flag_next; 513 513 } else { sprintf(error, "%d:%d: Unexpected ]", cur_line, e_off); -
lib/misc.c
re4f08bf r29ff5c2 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'; 189 193 } 190 194 in++; … … 295 299 296 300 /* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */ 297 /* This fu ction is safe, but make sure you call it safely as well! */301 /* This function is safe, but make sure you call it safely as well! */ 298 302 void http_encode(char *s) 299 303 { -
lib/proxy.c
re4f08bf r29ff5c2 51 51 #endif 52 52 53 static GHashTable *phb_hash = NULL; 54 53 55 struct PHB { 54 56 b_event_handler func, proxy_func; … … 61 63 }; 62 64 65 typedef int (*proxy_connect_func)(const char *host, unsigned short port_, struct PHB *phb); 66 63 67 static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb); 64 68 65 static gboolean phb_close(struct PHB *phb) 66 { 67 close(phb->fd); 68 phb->func(phb->data, -1, B_EV_IO_READ); 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 } 69 84 g_free(phb->host); 70 85 g_free(phb); … … 89 104 dup2(new_fd, source); 90 105 closesocket(new_fd); 106 phb->fd = source; 91 107 phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb); 92 108 return FALSE; … … 101 117 102 118 freeaddrinfo(phb->gai); 119 phb->gai = NULL; 120 103 121 b_event_remove(phb->inpa); 104 122 phb->inpa = 0; 123 105 124 if (phb->proxy_func) { 106 125 phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ); 107 126 } else { 108 127 phb->func(phb->data, source, B_EV_IO_READ); 109 g_free(phb);128 phb_free(phb, TRUE); 110 129 } 111 130 … … 171 190 172 191 if (fd < 0 && host) { 173 g_free(phb);192 phb_free(phb, TRUE); 174 193 } 175 194 … … 204 223 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) { 205 224 phb->func(phb->data, source, B_EV_IO_READ); 206 g_free(phb->host); 207 g_free(phb); 208 return FALSE; 209 } 210 211 return phb_close(phb); 225 return phb_free(phb, TRUE); 226 } 227 228 return phb_free(phb, FALSE); 212 229 } 213 230 … … 224 241 len = sizeof(error); 225 242 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 226 return phb_ close(phb);243 return phb_free(phb, FALSE); 227 244 } 228 245 sock_make_blocking(source); … … 231 248 phb->host, phb->port); 232 249 if (send(source, cmd, strlen(cmd), 0) < 0) { 233 return phb_ close(phb);250 return phb_free(phb, FALSE); 234 251 } 235 252 … … 242 259 g_free(t2); 243 260 if (send(source, cmd, strlen(cmd), 0) < 0) { 244 return phb_ close(phb);261 return phb_free(phb, FALSE); 245 262 } 246 263 } … … 248 265 g_snprintf(cmd, sizeof(cmd), "\r\n"); 249 266 if (send(source, cmd, strlen(cmd), 0) < 0) { 250 return phb_ close(phb);267 return phb_free(phb, FALSE); 251 268 } 252 269 … … 279 296 if (read(source, packet, 9) >= 4 && packet[1] == 90) { 280 297 phb->func(phb->data, source, B_EV_IO_READ); 281 g_free(phb->host); 282 g_free(phb); 283 return FALSE; 284 } 285 286 return phb_close(phb); 298 return phb_free(phb, TRUE); 299 } 300 301 return phb_free(phb, FALSE); 287 302 } 288 303 … … 294 309 socklen_t len; 295 310 int error = ETIMEDOUT; 311 gboolean is_socks4a = (proxytype == PROXY_SOCKS4A); 296 312 297 313 if (phb->inpa > 0) { … … 300 316 len = sizeof(error); 301 317 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 302 return phb_ close(phb);318 return phb_free(phb, FALSE); 303 319 } 304 320 sock_make_blocking(source); 305 321 306 /* XXX does socks4 not support host name lookups by the proxy? */ 307 if (!(hp = gethostbyname(phb->host))) { 308 return phb_close(phb); 322 if (!is_socks4a && !(hp = gethostbyname(phb->host))) { 323 return phb_free(phb, FALSE); 309 324 } 310 325 … … 313 328 packet[2] = phb->port >> 8; 314 329 packet[3] = phb->port & 0xff; 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]; 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 } 319 341 packet[8] = 0; 320 342 if (write(source, packet, 9) != 9) { 321 return phb_close(phb); 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 } 322 352 } 323 353 … … 348 378 349 379 if (read(source, buf, 10) < 10) { 350 return phb_ close(phb);380 return phb_free(phb, FALSE); 351 381 } 352 382 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { 353 return phb_ close(phb);383 return phb_free(phb, FALSE); 354 384 } 355 385 356 386 phb->func(phb->data, source, B_EV_IO_READ); 357 g_free(phb->host); 358 g_free(phb); 359 360 return FALSE; 387 return phb_free(phb, TRUE); 361 388 } 362 389 … … 377 404 378 405 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { 379 phb_ close(phb);406 phb_free(phb, FALSE); 380 407 return; 381 408 } … … 392 419 393 420 if (read(source, buf, 2) < 2) { 394 return phb_ close(phb);421 return phb_free(phb, FALSE); 395 422 } 396 423 397 424 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { 398 return phb_ close(phb);425 return phb_free(phb, FALSE); 399 426 } 400 427 … … 412 439 413 440 if (read(source, buf, 2) < 2) { 414 return phb_ close(phb);441 return phb_free(phb, FALSE); 415 442 } 416 443 417 444 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { 418 return phb_ close(phb);445 return phb_free(phb, FALSE); 419 446 } 420 447 … … 427 454 memcpy(buf + 2 + i + 1, proxypass, j); 428 455 if (write(source, buf, 3 + i + j) < 3 + i + j) { 429 return phb_ close(phb);456 return phb_free(phb, FALSE); 430 457 } 431 458 … … 451 478 len = sizeof(error); 452 479 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 453 return phb_ close(phb);480 return phb_free(phb, FALSE); 454 481 } 455 482 sock_make_blocking(source); … … 469 496 470 497 if (write(source, buf, i) < i) { 471 return phb_ close(phb);498 return phb_free(phb, FALSE); 472 499 } 473 500 … … 487 514 } 488 515 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 }; 489 523 490 524 /* Export functions */ … … 493 527 { 494 528 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 } 495 535 496 536 if (!host || port <= 0 || !func || strlen(host) > 128) { … … 502 542 phb->data = data; 503 543 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 } 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 } -
lib/proxy.h
re4f08bf r29ff5c2 40 40 #define PROXY_SOCKS4 2 41 41 #define PROXY_SOCKS5 3 42 #define PROXY_SOCKS4A 4 42 43 43 44 extern char proxyhost[128]; … … 48 49 49 50 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); 50 52 51 53 #endif /* _PROXY_H_ */ -
lib/ssl_gnutls.c
re4f08bf r29ff5c2 455 455 } 456 456 457 closesocket(conn->fd);457 proxy_disconnect(conn->fd); 458 458 459 459 if (conn->session) { -
lib/ssl_nss.c
re4f08bf r29ff5c2 226 226 if (conn->prfd) { 227 227 PR_Close(conn->prfd); 228 } 229 if (source >= 0) {228 } else if (source >= 0) { 229 /* proxy_disconnect() would be redundant here */ 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); 307 309 } 308 310 -
lib/ssl_openssl.c
re4f08bf r29ff5c2 131 131 conn->func(conn->data, 1, NULL, cond); 132 132 if (source >= 0) { 133 closesocket(source);133 proxy_disconnect(source); 134 134 } 135 135 ssl_conn_free(conn); … … 276 276 } 277 277 278 closesocket(conn->fd);278 proxy_disconnect(conn->fd); 279 279 280 280 ssl_conn_free(conn); -
lib/url.c
re4f08bf r29ff5c2 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; 50 52 } else { 51 53 return 0; -
lib/url.h
re4f08bf r29ff5c2 30 30 #define PROTO_SOCKS4 3 31 31 #define PROTO_SOCKS5 4 32 #define PROTO_SOCKS4A 5 32 33 #define PROTO_DEFAULT PROTO_HTTP 33 34 -
log.c
re4f08bf r29ff5c2 51 51 void log_link(int level, int output) 52 52 { 53 /* I know it's ugly, but it works and I didn't feel like messing with pointer to function pointers */ 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 } 54 64 55 65 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 } 66 logoutput.informational = output_function; 65 67 } else if (level == LOGLVL_WARNING) { 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 } 68 logoutput.warning = output_function; 75 69 } else if (level == LOGLVL_ERROR) { 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 } 70 logoutput.error = output_function; 85 71 } 86 72 #ifdef DEBUG 87 73 else if (level == LOGLVL_DEBUG) { 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 } 74 logoutput.debug = output_function; 97 75 } 98 76 #endif -
otr.c
re4f08bf r29ff5c2 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 erately */189 i.e. msgstate should be announced separately */ 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 218 222 /* functions to be called for certain events */ 219 223 static const struct irc_plugin otr_plugin; 224 225 #define OTR_COLOR_TRUSTED "03" /* green */ 226 #define OTR_COLOR_UNTRUSTED "05" /* red */ 220 227 221 228 /*** routines declared in otr.h: ***/ … … 434 441 435 442 /* don't do OTR on certain (not classic IM) protocols, e.g. twitter */ 436 if (ic->acc->prpl->options & OPT_NOOTR) { 443 if (ic->acc->prpl->options & OPT_NOOTR || 444 iu->bu->flags & BEE_USER_NOOTR) { 437 445 return msg; 438 446 } … … 451 459 } else if (!newmsg) { 452 460 /* this was a non-OTR message */ 453 return msg;461 return otr_filter_colors(msg); 454 462 } else { 455 463 /* we're done with the original msg, which will be caller-freed. */ … … 472 480 473 481 /* don't do OTR on certain (not classic IM) protocols, e.g. twitter */ 474 if (ic->acc->prpl->options & OPT_NOOTR) { 482 if (ic->acc->prpl->options & OPT_NOOTR || 483 iu->bu->flags & BEE_USER_NOOTR) { 475 484 return msg; 476 485 } … … 742 751 } 743 752 753 static char *otr_filter_colors(char *msg) { 754 int i; 755 for (i = 0; msg[i]; i++) { 756 if (msg[i] == '\x02' || msg[i] == '\x03') { 757 msg[i] = '?'; 758 } 759 } 760 return msg; 761 } 762 763 /* returns newly allocated string */ 764 static char *otr_color_encrypted(char *msg, char *color, gboolean is_query) { 765 char **lines; 766 GString *out; 767 int i; 768 769 lines = g_strsplit(msg, "\n", -1); 770 771 /* up to 4 extra chars per line (e.g., '\x03' + ("03"|"05") + ' ') */ 772 out = g_string_sized_new(strlen(msg) + g_strv_length(lines) * 4); 773 774 for (i = 0; lines[i]; i++) { 775 char *line = lines[i]; 776 777 if (i != 0) { 778 g_string_append_c(out, '\n'); 779 780 } else if (is_query && g_strncasecmp(line, "/me ", 4) == 0) { 781 /* in a query window, keep "/me " uncolored at the beginning */ 782 line += 4; 783 g_string_append(out, "/me "); 784 } 785 786 g_string_append_c(out, '\x03'); 787 g_string_append(out, color); 788 789 /* comma in first place could mess with the color code */ 790 if (line[0] == ',') { 791 /* insert a space between color spec and message */ 792 g_string_append_c(out, ' '); 793 } 794 795 g_string_append(out, otr_filter_colors(line)); 796 } 797 798 g_strfreev(lines); 799 800 return g_string_free(out, FALSE); 801 } 802 744 803 void op_convert_msg(void *opdata, ConnContext *ctx, OtrlConvertType typ, 745 804 char **dst, const char *src) … … 752 811 if (typ == OTRL_CONVERT_RECEIVING) { 753 812 char *msg = g_strdup(src); 754 char *buf = msg;755 813 756 814 /* HTML decoding */ … … 759 817 set_getbool(&ic->bee->set, "strip_html")) { 760 818 strip_html(msg); 819 820 /* msg is borrowed by *dst (unless the next if decides to color it) */ 761 821 *dst = msg; 762 822 } … … 764 824 /* coloring */ 765 825 if (set_getbool(&ic->bee->set, "otr_color_encrypted")) { 766 int color; /* color according to f'print trust */767 char *pre = "", *sep = ""; /* optional parts */768 826 const char *trust = ctx->active_fingerprint->trust; 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); 827 char *color = (trust && *trust) ? OTR_COLOR_TRUSTED : OTR_COLOR_UNTRUSTED; 828 gboolean is_query = (irc_user_msgdest(iu) == irc->user->nick); 829 830 /* the return value of otr_color_encrypted() is borrowed by *dst */ 831 *dst = otr_color_encrypted(msg, color, is_query); 832 833 /* this branch doesn't need msg */ 834 g_free(msg); 792 835 } 793 836 } else { … … 1357 1400 1358 1401 if (u) { 1359 /* display as a notice from this particular user*/1360 irc_user notice(u, "%s", msg);1402 /* just show this as a regular message */ 1403 irc_usermsg(u, "<<\002OTR\002>> %s", msg); 1361 1404 } else { 1362 1405 irc_rootmsg(irc, "[otr] %s", msg); … … 1695 1738 *p = '\0'; 1696 1739 1740 /* remove trailing whitespace */ 1741 g_strchomp(prefix); 1742 1697 1743 /* find first key which matches the given prefix */ 1698 1744 n = strlen(prefix); -
protocols/bee.h
re4f08bf r29ff5c2 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 */ 64 65 } bee_user_flags_t; 65 66 … … 104 105 gboolean (*user_status)(bee_t *bee, struct bee_user *bu, struct bee_user *old); 105 106 /* On every incoming message. sent_at = 0 means unknown. */ 106 gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at);107 gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at); 107 108 /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */ 108 109 gboolean (*user_typing)(bee_t *bee, bee_user_t *bu, guint32 flags); … … 119 120 /* System messages of any kind. */ 120 121 gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text); 121 gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at);122 gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at); 122 123 gboolean (*chat_add_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu); 123 gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu );124 gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *reason); 124 125 gboolean (*chat_topic)(bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu); 125 126 gboolean (*chat_name_hint)(bee_t *bee, struct groupchat *c, const char *name); -
protocols/bee_chat.c
re4f08bf r29ff5c2 104 104 } 105 105 106 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_tflags, time_t sent_at)106 void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at) 107 107 { 108 108 struct im_connection *ic = c->ic; 109 109 bee_t *bee = ic->bee; 110 110 bee_user_t *bu; 111 gboolean temp ;111 gboolean temp = FALSE; 112 112 char *s; 113 113 114 /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ 115 if (handle_is_self(ic, who)) { 114 if (handle_is_self(ic, who) && !(flags & OPT_SELFMESSAGE)) { 116 115 return; 117 116 } … … 131 130 132 131 if (bee->ui->chat_msg) { 133 bee->ui->chat_msg(bee, c, bu, msg, sent_at);132 bee->ui->chat_msg(bee, c, bu, msg, flags, sent_at); 134 133 } 135 134 … … 239 238 240 239 if (bee->ui->chat_remove_user && bu) { 241 bee->ui->chat_remove_user(bee, c, bu );240 bee->ui->chat_remove_user(bee, c, bu, reason); 242 241 } 243 242 } -
protocols/bee_user.c
re4f08bf r29ff5c2 247 247 } 248 248 249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, uint32_tflags, time_t sent_at)249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32 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, sent_at);267 bee->ui->user_msg(bee, bu, msg, flags, 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, uint32_tflags)299 void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags) 300 300 { 301 301 bee_user_t *bu; -
protocols/ft.h
re4f08bf r29ff5c2 58 58 * | accept 59 59 * V 60 * /------ /-------------\ /------------------------ \61 * out_of_data | | TRANSFER ING | -----------------> | TRANSFERING | CANCELED |62 * \-----> \-------------/ [canceled,]free \------------------------ /60 * /------ /-------------\ /--------------------------\ 61 * out_of_data | | TRANSFERRING | -----------------> | TRANSFERRING | CANCELED | 62 * \-----> \-------------/ [canceled,]free \--------------------------/ 63 63 * | 64 64 * | finished,free 65 65 * V 66 * /------------------------ \67 * | TRANSFER ING | FINISHED |68 * \------------------------ /66 * /-------------------------\ 67 * | TRANSFERRING | FINISHED | 68 * \-------------------------/ 69 69 */ 70 70 typedef struct file_transfer { … … 115 115 116 116 /* 117 * If set, called after succes ful connection setup.117 * If set, called after successful connection setup. 118 118 */ 119 119 void (*accept)(struct file_transfer *file); -
protocols/jabber/conference.c
re4f08bf r29ff5c2 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); 28 29 29 30 struct groupchat *jabber_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password) … … 127 128 } 128 129 130 static xt_status jabber_chat_self_message(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 131 { 132 /* This is a self message sent by this bitlbee - just drop it */ 133 return XT_ABORT; 134 } 135 129 136 struct groupchat *jabber_chat_by_jid(struct im_connection *ic, const char *name) 130 137 { … … 171 178 node = jabber_make_packet("message", "groupchat", jc->name, node); 172 179 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; 180 jabber_cache_add(ic, node, jabber_chat_self_message); 181 182 return !jabber_write_packet(ic, node); 180 183 } 181 184 … … 299 302 } 300 303 } 301 302 /* Some program-specific restrictions. */303 imcb_clean_handle(ic, bud->ext_jid);304 304 } 305 305 bud->flags |= JBFLAG_IS_ANONYMOUS; … … 331 331 } else if (type) { /* type can only be NULL or "unavailable" in this function */ 332 332 if ((bud->flags & JBFLAG_IS_CHATROOM) && bud->ext_jid) { 333 char *reason = NULL; 334 char *status = NULL; 335 char *status_text = NULL; 336 337 if ((c = xt_find_node_by_attr(node->children, "x", "xmlns", XMLNS_MUC_USER))) { 338 struct xt_node *c2 = c->children; 339 340 while ((c2 = xt_find_node(c2, "status"))) { 341 char *code = xt_find_attr(c2, "code"); 342 if (g_strcmp0(code, "301") == 0) { 343 status = "Banned"; 344 break; 345 } else if (g_strcmp0(code, "303") == 0) { 346 /* This could be handled in a cleverer way, 347 * but let's just show a literal part/join for now */ 348 status = "Changing nicks"; 349 break; 350 } else if (g_strcmp0(code, "307") == 0) { 351 status = "Kicked"; 352 break; 353 } 354 c2 = c2->next; 355 } 356 357 /* Sometimes the status message is in presence/x/item/reason */ 358 if ((c2 = xt_find_path(c, "item/reason")) && c2->text && c2->text_len) { 359 status_text = c2->text; 360 } 361 } 362 363 /* Sometimes the status message is right inside <presence> */ 364 if ((c = xt_find_node(node->children, "status")) && c->text && c->text_len) { 365 status_text = c->text; 366 } 367 368 if (status_text && status) { 369 reason = g_strdup_printf("%s: %s", status, status_text); 370 } else { 371 reason = g_strdup(status_text ? : status); 372 } 373 333 374 s = strchr(bud->ext_jid, '/'); 334 375 if (s) { 335 376 *s = 0; 336 377 } 337 imcb_chat_remove_buddy(chat, bud->ext_jid, NULL);378 imcb_chat_remove_buddy(chat, bud->ext_jid, reason); 338 379 if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) { 339 imcb_remove_buddy(ic, bud->ext_jid, NULL);380 imcb_remove_buddy(ic, bud->ext_jid, reason); 340 381 } 341 382 if (s) { 342 383 *s = '/'; 343 384 } 385 386 g_free(reason); 344 387 } 345 388 … … 360 403 char *final_from = NULL; 361 404 char *bare_jid = NULL; 405 guint32 flags = 0; 362 406 363 407 from = (bud) ? bud->full_jid : xt_find_attr(node, "from"); … … 396 440 397 441 if (subject && chat) { 398 char *subject_text = subject->text_len > 0 ? subject->text : NULL;442 char *subject_text = subject->text_len > 0 ? subject->text : ""; 399 443 if (g_strcmp0(chat->topic, subject_text) != 0) { 400 444 bare_jid = (bud) ? jabber_get_bare_jid(bud->ext_jid) : NULL; … … 402 446 jabber_get_timestamp(node)); 403 447 g_free(bare_jid); 448 bare_jid = NULL; 404 449 } 405 450 } … … 422 467 imcb_chat_log(chat, "From conference server: %s", body->text); 423 468 return; 424 } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me ) {425 /* exclude self-messages since they would get filtered out426 * but not the ones in the backlog*/469 } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me && 470 (jabber_cache_handle_packet(ic, node) == XT_ABORT)) { 471 /* Self message marked by this bitlbee, don't show it */ 427 472 return; 428 473 } 429 474 430 if (bud && jc && bud != jc->me) {475 if (bud) { 431 476 bare_jid = jabber_get_bare_jid(bud->ext_jid ? bud->ext_jid : bud->full_jid); 432 477 final_from = bare_jid; 478 flags = (bud == jc->me) ? OPT_SELFMESSAGE : 0; 433 479 } else { 434 480 final_from = nick; 435 481 } 436 482 437 imcb_chat_msg(chat, final_from, body->text, 0, jabber_get_timestamp(node));483 imcb_chat_msg(chat, final_from, body->text, flags, jabber_get_timestamp(node)); 438 484 439 485 g_free(bare_jid); -
protocols/jabber/io.c
re4f08bf r29ff5c2 147 147 } 148 148 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) { 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 { 169 209 imcb_error(ic, "XML stream error"); 170 210 imc_logout(ic, TRUE); 171 211 return FALSE; 172 212 } 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. */ 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)) { 178 238 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 xmltree190 has nifty event handler stuff, it only calls handlers191 when nodes are complete. Since the server should only192 send an opening <stream:stream> tag, we have to check193 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, assume199 this is an old server that can't do SASL200 authentication. */201 if (!set_getbool(&ic->acc->set, "sasl") || !sasl_supported(ic)) {202 /* If there's no version= tag, we suppose203 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 }219 239 } 220 240 } else if (st == 0 || (st < 0 && !ssl_sockerr_again(jd->ssl))) { -
protocols/jabber/iq.c
re4f08bf r29ff5c2 385 385 struct xt_node *response; 386 386 struct jabber_data *jd = ic->proto_data; 387 388 response = jabber_make_packet("iq", "result", g_strdup_printf("%s@%s", jd->username, jd->server), NULL);387 388 response = jabber_make_packet("iq", "result", jd->me, NULL); 389 389 390 390 jabber_cache_add(ic, response, NULL); -
protocols/jabber/jabber.c
re4f08bf r29ff5c2 85 85 set_setstr(&acc->set, "server", "chat.hipchat.com"); 86 86 } else { 87 s = set_add(&acc->set, "oauth", "false", set_eval_oauth, acc); 87 set_add(&acc->set, "oauth", "false", set_eval_oauth, acc); 88 89 /* this reuses set_eval_oauth, which clears the password */ 90 set_add(&acc->set, "anonymous", "false", set_eval_oauth, acc); 88 91 } 89 92 … … 194 197 } else { 195 198 jabber_connect(ic); 199 } 200 } 201 202 static void jabber_xmlconsole_enable(struct im_connection *ic) 203 { 204 struct jabber_data *jd = ic->proto_data; 205 const char *handle = JABBER_XMLCONSOLE_HANDLE; 206 bee_user_t *bu; 207 208 jd->flags |= JFLAG_XMLCONSOLE; 209 210 if (!(bu = bee_user_by_handle(ic->bee, ic, handle))) { 211 bu = bee_user_new(ic->bee, ic, handle, 0); 212 bu->flags |= BEE_USER_NOOTR; 196 213 } 197 214 } … … 263 280 264 281 if (set_getbool(&acc->set, "xmlconsole")) { 265 jd->flags |= JFLAG_XMLCONSOLE; 266 /* Shouldn't really do this at this stage already, maybe. But 267 I think this shouldn't break anything. */ 268 imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL); 282 jabber_xmlconsole_enable(ic); 269 283 } 270 284 … … 331 345 } 332 346 if (jd->fd >= 0) { 333 closesocket(jd->fd);347 proxy_disconnect(jd->fd); 334 348 } 335 349 … … 342 356 } 343 357 344 jabber_buddy_remove_all(ic); 358 if (jd->buddies) { 359 jabber_buddy_remove_all(ic); 360 } 345 361 346 362 xt_free(jd->xt); … … 469 485 static void jabber_add_buddy(struct im_connection *ic, char *who, char *group) 470 486 { 471 struct jabber_data *jd = ic->proto_data;472 473 487 if (g_strcasecmp(who, JABBER_XMLCONSOLE_HANDLE) == 0) { 474 jd->flags |= JFLAG_XMLCONSOLE; 475 imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL); 488 jabber_xmlconsole_enable(ic); 476 489 return; 477 490 } … … 587 600 { 588 601 struct jabber_data *jd = ic->proto_data; 589 struct jabber_buddy *bud ;602 struct jabber_buddy *bud, *bare; 590 603 591 604 /* Enable typing notification related code from now. */ 592 605 jd->flags |= JFLAG_WANT_TYPING; 593 606 594 if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL) { 607 if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL || 608 (bare = jabber_buddy_by_jid(ic, who, GET_BUDDY_BARE)) == NULL) { 595 609 /* Sending typing notifications to unknown buddies is 596 610 unsupported for now. Shouldn't be a problem, I think. */ … … 598 612 } 599 613 600 if (bud->flags & JBFLAG_DOES_XEP85) { 614 615 if (bud->flags & JBFLAG_DOES_XEP85 || bare->flags & JBFLAG_DOES_XEP85) { 601 616 /* We're only allowed to send this stuff if we know the other 602 side supports it. */ 617 side supports it. If the bare JID has the flag, all other 618 resources get it, too (That is the case in gtalk) */ 603 619 604 620 struct xt_node *node; -
protocols/jabber/jabber_util.c
re4f08bf r29ff5c2 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 return NULL; 516 if (head != bud && head->resource == NULL) { 517 return head; 518 } else { 519 return NULL; 520 } 517 521 } else if (bud->resource == NULL || bud->next == NULL) { 518 522 /* No need for selection if there's only one option. */ -
protocols/jabber/message.c
re4f08bf r29ff5c2 37 37 if (!from) { 38 38 return XT_HANDLED; /* Consider this packet corrupted. */ 39 } 39 40 40 } 41 if (request && id) { 41 if (request && id && g_strcmp0(type, "groupchat") != 0) { 42 42 /* Send a message receipt (XEP-0184), looking like this: 43 * <message 44 * from='kingrichard@royalty.england.lit/throne' 45 * id='bi29sg183b4v' 46 * to='northumberland@shakespeare.lit/westminster'> 43 * <message from='...' id='...' to='...'> 47 44 * <received xmlns='urn:xmpp:receipts' id='richard2-4.1.247'/> 48 * </message> */ 45 * </message> 46 * 47 * MUC messages are excluded, since receipts aren't supposed to be sent over MUCs 48 * (XEP-0184 section 5.3) and replying to those may result in 'forbidden' errors. 49 */ 49 50 struct xt_node *received, *receipt; 50 51 … … 142 143 imcb_buddy_typing(ic, from, OPT_TYPING); 143 144 } 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)) { 145 else if (xt_find_node(node->children, "active")) { 146 146 bud->flags |= JBFLAG_DOES_XEP85; 147 imcb_buddy_typing(ic, from, 0); 147 148 /* No need to send a "stopped typing" signal when there's a message. */ 149 if (body == NULL) { 150 imcb_buddy_typing(ic, from, 0); 151 } 148 152 } else if (xt_find_node(node->children, "paused")) { 149 153 bud->flags |= JBFLAG_DOES_XEP85; -
protocols/jabber/s5bytestream.c
re4f08bf r29ff5c2 85 85 return jabber_bs_abort(bt, msg ": %s", strerror(errno)); } 86 86 87 gboolean jabber_bs_abort(struct bs_transfer *bt, char *format, ...) ;87 gboolean jabber_bs_abort(struct bs_transfer *bt, char *format, ...) G_GNUC_PRINTF(2, 3); 88 88 void jabber_bs_canceled(file_transfer_t *ft, char *reason); 89 89 void jabber_bs_free_transfer(file_transfer_t *ft); … … 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 nt matter */538 * is sending, it should not 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 cessary. This of course also means, that the timeout561 * slow proxy is only used if necessary. 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
re4f08bf r29ff5c2 54 54 struct xt_node *c, *reply; 55 55 char *s; 56 int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0 ;57 int want_oauth = FALSE, want_hipchat = FALSE ;56 int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0, sup_anonymous = 0; 57 int want_oauth = FALSE, want_hipchat = FALSE, want_anonymous = FALSE; 58 58 GString *mechs; 59 59 … … 74 74 } 75 75 76 want_anonymous = set_getbool(&ic->acc->set, "anonymous"); 76 77 want_oauth = set_getbool(&ic->acc->set, "oauth"); 77 78 want_hipchat = (jd->flags & JFLAG_HIPCHAT); … … 84 85 } else if (c->text && g_strcasecmp(c->text, "DIGEST-MD5") == 0) { 85 86 sup_digest = 1; 87 } else if (c->text && g_strcasecmp(c->text, "ANONYMOUS") == 0) { 88 sup_anonymous = 1; 86 89 } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) { 87 90 sup_gtalk = 1; … … 142 145 xt_free_node(reply); 143 146 return XT_ABORT; 144 } else if (sup_digest) { 147 } else if (want_anonymous && sup_anonymous) { 148 xt_add_attr(reply, "mechanism", "ANONYMOUS"); 149 150 /* Well, that was easy. */ 151 } else if (want_anonymous) { 152 imcb_error(ic, "Anonymous login requested, but not supported by server"); 153 imc_logout(ic, FALSE); 154 xt_free_node(reply); 155 return XT_ABORT; 156 } else if (sup_digest && !(jd->ssl && sup_plain)) { 157 /* Only try DIGEST-MD5 if there's no SSL/TLS or if PLAIN isn't supported. 158 * Which in practice means "don't bother with DIGEST-MD5 most of the time". 159 * It's weak, pointless over TLS, and often breaks with some servers (hi openfire) */ 160 145 161 xt_add_attr(reply, "mechanism", "DIGEST-MD5"); 146 162 -
protocols/jabber/si.c
re4f08bf r29ff5c2 186 186 jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); 187 187 188 /* query buddy's features and server's streaming proxies if nec cessary */188 /* query buddy's features and server's streaming proxies if necessary */ 189 189 190 190 if (!tf->bud->features) { … … 283 283 284 284 if (requestok) { 285 /* Figure out who the transfer should come from e... */285 /* Figure out who the transfer should come from... */ 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 cessary405 * [ <file xmlns=ft/> ] <-- not necessary 406 406 * <feature xmlns=feature> 407 407 * <x xmlns=xdata type=submit> -
protocols/msn/ns.c
re4f08bf r29ff5c2 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 );41 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage); 42 42 static void msn_ns_nfy(struct msn_data *md, char *who, char **parts, char *action, gboolean is_put); 43 43 … … 475 475 } 476 476 477 /* returns newly allocated string */ 478 static char *msn_ns_parse_header_address(struct msn_data *md, char *headers, char *header_name) 479 { 480 char *semicolon = NULL; 481 char *header = NULL; 482 char *address = NULL; 483 484 if (!(header = get_rfc822_header(headers, header_name, 0))) { 485 return NULL; 486 } 487 488 /* either the semicolon or the end of the string */ 489 semicolon = strchr(header, ';') ? : (header + strlen(header)); 490 491 address = g_strndup(header + 2, semicolon - header - 2); 492 493 g_free(header); 494 return address; 495 } 496 477 497 static void msn_ns_structured_message(struct msn_data *md, char *msg, int msglen, char **cmd) 478 498 { 479 499 char **parts = NULL; 480 char *semicolon = NULL;481 500 char *action = NULL; 482 char *from = NULL;483 501 char *who = NULL; 502 gboolean selfmessage = FALSE; 484 503 485 504 parts = g_strsplit(msg, "\r\n\r\n", 4); 486 505 487 if (!( from = get_rfc822_header(parts[0], "From", 0))) {506 if (!(who = msn_ns_parse_header_address(md, parts[0], "From"))) { 488 507 goto cleanup; 489 508 } 490 509 491 /* either the semicolon or the end of the string */ 492 semicolon = strchr(from, ';') ? : (from + strlen(from)); 493 494 who = g_strndup(from + 2, semicolon - from - 2); 510 if (strcmp(who, md->ic->acc->user) == 0) { 511 selfmessage = TRUE; 512 g_free(who); 513 if (!(who = msn_ns_parse_header_address(md, parts[0], "To"))) { 514 goto cleanup; 515 } 516 } 495 517 496 518 if ((strcmp(cmd[0], "SDG") == 0) && (action = get_rfc822_header(parts[2], "Message-Type", 0))) { 497 msn_ns_sdg(md, who, parts, action );519 msn_ns_sdg(md, who, parts, action, selfmessage); 498 520 499 521 } else if ((strcmp(cmd[0], "NFY") == 0) && (action = get_rfc822_header(parts[2], "Uri", 0))) { … … 505 527 g_strfreev(parts); 506 528 g_free(action); 507 g_free(from);508 529 g_free(who); 509 530 } 510 531 511 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action )532 static void msn_ns_sdg(struct msn_data *md, char *who, char **parts, char *action, gboolean selfmessage) 512 533 { 513 534 struct im_connection *ic = md->ic; 514 535 515 if (strcmp(action, "Control/Typing") == 0 ) {536 if (strcmp(action, "Control/Typing") == 0 && !selfmessage) { 516 537 imcb_buddy_typing(ic, who, OPT_TYPING); 517 538 } else if (strcmp(action, "Text") == 0) { 518 imcb_buddy_msg(ic, who, parts[3], 0, 0);539 imcb_buddy_msg(ic, who, parts[3], selfmessage ? OPT_SELFMESSAGE : 0, 0); 519 540 } 520 541 } … … 595 616 } else { 596 617 imcb_error(ic, "Error during Passport authentication: %s", error); 597 imc_logout(ic, TRUE); 618 619 /* don't reconnect with auth errors */ 620 if (error && g_str_has_prefix(error, "wsse:FailedAuthentication")) { 621 imc_logout(ic, FALSE); 622 } else { 623 imc_logout(ic, TRUE); 624 } 598 625 } 599 626 } -
protocols/msn/soap.c
re4f08bf r29ff5c2 327 327 struct xt_node *code = xt_find_node(node->children, "faultcode"); 328 328 struct xt_node *string = xt_find_node(node->children, "faultstring"); 329 struct xt_node *reqstatus = xt_find_path(node, "psf:pp/psf:reqstatus"); 329 330 struct xt_node *url; 330 331 … … 335 336 url->text_len > 0) { 336 337 sd->redirect = g_strdup(url->text); 338 } else if (reqstatus && strcmp(reqstatus->text, "0x800488fe") == 0) { 339 char *msg = "Location blocked. Log in to live.com, go to recent activity and click 'this was me'"; 340 sd->error = g_strdup_printf("%s (%s)", code->text, msg); 337 341 } else { 338 342 sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ? … … 346 350 { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", msn_soap_passport_sso_token }, 347 351 { "S:Fault", "S:Envelope", msn_soap_passport_failure }, 352 { "S:Fault", "wst:RequestSecurityTokenResponse", msn_soap_passport_failure }, 348 353 { NULL, NULL, NULL } 349 354 }; -
protocols/nogaim.c
re4f08bf r29ff5c2 735 735 } 736 736 737 /* Deprecated: using this function resulted in merging several handles accidentally 738 * Also the irc layer handles this decently nowadays */ 737 739 void imcb_clean_handle(struct im_connection *ic, char *handle) 738 740 { 739 /* Accepts a handle and does whatever is necessary to make it 740 BitlBee-friendly. Currently this means removing everything 741 outside 33-127 (ASCII printable excl spaces), @ (only one 742 is allowed) and ! and : */ 743 char out[strlen(handle) + 1]; 744 int s, d; 745 746 s = d = 0; 747 while (handle[s]) { 748 if (handle[s] > ' ' && handle[s] != '!' && handle[s] != ':' && 749 (handle[s] & 0x80) == 0) { 750 if (handle[s] == '@') { 751 /* See if we got an @ already? */ 752 out[d] = 0; 753 if (strchr(out, '@')) { 754 continue; 755 } 756 } 757 758 out[d++] = handle[s]; 759 } 760 s++; 761 } 762 out[d] = handle[s]; 763 764 strcpy(handle, out); 765 } 741 } -
protocols/nogaim.h
re4f08bf r29ff5c2 70 70 #define OPT_PONGS 0x00010000 /* Service sends us keep-alives */ 71 71 #define OPT_PONGED 0x00020000 /* Received a keep-alive during last interval */ 72 #define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */ 72 73 73 74 /* ok. now the fun begins. first we create a connection structure */ … … 325 326 G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data); 326 327 327 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_tflags);328 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags); 328 329 G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle(struct im_connection *ic, const char *handle); 329 G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle); 330 331 G_GNUC_DEPRECATED G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle); 330 332 331 333 /* Actions, or whatever. */ -
protocols/oscar/aim.h
re4f08bf r29ff5c2 871 871 * SNAC Family: Internal Messages 872 872 * 873 * This isn't tru ely a SNAC family either, but using873 * This isn't truly a SNAC family either, but using 874 874 * these, we can integrated non-SNAC services into 875 875 * the SNAC-centered libfaim callback structure. -
protocols/oscar/auth.c
re4f08bf r29ff5c2 41 41 * meaning you generally never call this. 42 42 * 43 * But there are times when something might want it sep erate. Specifically,43 * But there are times when something might want it separate. Specifically, 44 44 * libfaim sends this internally when doing SNAC login. 45 45 * -
protocols/oscar/conn.c
re4f08bf r29ff5c2 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 enteed a "Not supported" SNAC error.17 * without being guaranteed 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 ly not that twit38 * the module that decided to send this SNAC, and definitely 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 closesocket(deadconn->fd);319 proxy_disconnect(deadconn->fd); 320 320 } 321 321 deadconn->fd = -1; -
protocols/oscar/im.c
re4f08bf r29ff5c2 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 elent to ASCII7, however they52 * the first 128 UNICODE symbols are equivalent 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 yed out. Most obviously, tlvlists should be used66 * supposed to be laid 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 ly recommend avoiding this feature unless you really478 * I would definitely 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 ary... */640 /* XXX this isn't really necessary... */ 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 vous"1163 * other channels for things called "rendezvous" 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 vous channel, which1167 * Channel 0x0002 is the Rendezvous 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 eration.1183 * information, the rest are not even though there is no separation. 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 ly recommend sending this. If you don't, you'll be stuck1255 * I definitely 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
re4f08bf r29ff5c2 3 3 * aim_misc.c 4 4 * 5 * TODO: Sep erate a lot of this into an aim_bos.c.5 * TODO: Separate a lot of this into an aim_bos.c. 6 6 * 7 7 * Other things... -
protocols/oscar/msgcookie.c
re4f08bf r29ff5c2 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 ehlist of cookies144 * this function removes the cookie *cookie from the 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
re4f08bf r29ff5c2 456 456 b_event_remove(n->inpa); 457 457 } 458 n->inpa = 0; 458 459 g_free(n->name); 459 460 g_free(n->show); … … 481 482 if (ic->inpa > 0) { 482 483 b_event_remove(ic->inpa); 484 ic->inpa = 0; 483 485 } 484 486 if (odata->cnpa > 0) { 485 487 b_event_remove(odata->cnpa); 488 odata->cnpa = 0; 486 489 } 487 490 if (odata->paspa > 0) { 488 491 b_event_remove(odata->paspa); 492 odata->paspa = 0; 489 493 } 490 494 aim_session_kill(odata->sess); … … 637 641 aim_sendcookie(sess, bosconn, info->cookie); 638 642 b_event_remove(ic->inpa); 643 ic->inpa = 0; 639 644 640 645 return 1; … … 1261 1266 } break; 1262 1267 1263 case 2: { /* rende vous */1268 case 2: { /* rendezvous */ 1264 1269 struct aim_incomingim_ch2_args *args; 1265 1270 args = va_arg(ap, struct aim_incomingim_ch2_args *); … … 2586 2591 if (cc->inpa > 0) { 2587 2592 b_event_remove(cc->inpa); 2593 cc->inpa = 0; 2588 2594 } 2589 2595 aim_conn_kill(od->sess, &cc->conn); -
protocols/oscar/rxhandlers.c
re4f08bf r29ff5c2 381 381 /* 382 382 * This doesn't have to be called here. It could easily be done 383 * by a sep erate thread or something. It's an administrative operation,383 * by a separate 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
re4f08bf r29ff5c2 361 361 /* 362 362 * Grab a single command sequence off the socket, and enqueue 363 * it in the incoming event queue in a sep erate struct.363 * it in the incoming event queue in a separate struct. 364 364 */ 365 365 int aim_get_command(aim_session_t *sess, aim_conn_t *conn) … … 479 479 480 480 /* 481 * Purge rec ieve queue of all handled commands (->handled==1). Also481 * Purge receive 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
re4f08bf r29ff5c2 157 157 158 158 /* 159 * OSCAR defines several 'rate classes'. Each class has sep erate159 * OSCAR defines several 'rate classes'. Each class has separate 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 ieves this request.)712 * 713 * When the client rec ieves the request, it adds it to the current ds711 * before the client receives this request.) 712 * 713 * When the client receives 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 ieving disconnect code 1, URL725 * The connection is then closed, receiving 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 ly suspect this code729 * not just sending back a bad hash. Do not immediately 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 assions.732 * on numerous occasions. 733 733 * 734 734 * Anyway, neener. We win again. -
protocols/oscar/tlv.c
re4f08bf r29ff5c2 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 ecient as the in-place TLV parsing used in a couple places27 * just as efficient 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 nation chain (%NULL pointer if empty)137 * @list: Designation chain (%NULL pointer if empty) 138 138 * @type: TLV type 139 139 * @str: String to add -
protocols/oscar/txqueue.c
re4f08bf r29ff5c2 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 ent copy of the struct69 * 1) Make a scope-irrelevant copy of the struct 70 70 * 3) Mark as not-sent-yet 71 71 * 4) Enqueue the struct into the list -
protocols/purple/purple.c
re4f08bf r29ff5c2 113 113 servers anyway! */ 114 114 if (!dir_fixed) { 115 PurpleCertificatePool *pool; 115 116 irc_t *irc = acc->bee->ui_data; 116 117 char *dir; … … 122 123 purple_blist_load(); 123 124 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 124 136 dir_fixed = TRUE; 125 137 } … … 1404 1416 PurpleProxyInfo *pi = purple_global_proxy_get_info(); 1405 1417 switch (proxytype) { 1418 case PROXY_SOCKS4A: 1406 1419 case PROXY_SOCKS4: 1407 1420 purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS4); -
protocols/skype/README
re4f08bf r29ff5c2 203 203 204 204 * `account skype set skypeconsole_receive true` will make the 205 `skypeconsole` account dump all the rec ieved raw traffic for you205 `skypeconsole` account dump all the received raw traffic for you 206 206 207 207 - If you want to automatically join bookmarked groupchats right after -
protocols/skype/skype.c
re4f08bf r29ff5c2 21 21 22 22 #define _XOPEN_SOURCE 23 #define _BSD_SOURCE24 23 #include <poll.h> 25 24 #include <stdio.h> … … 188 187 189 188 va_start(args, fmt); 190 vsnprintf(str, IRC_LINE_SIZE, fmt, args);189 g_vsnprintf(str, IRC_LINE_SIZE, fmt, args); 191 190 va_end(args); 192 191 … … 322 321 } 323 322 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; 324 341 } 325 342 … … 688 705 info += 9; 689 706 if (sd->handle && sd->body && sd->type) { 690 struct groupchat *gc = bee_chat_by_title(ic->bee,ic, info);707 struct groupchat *gc = skype_chat_get_or_create(ic, info); 691 708 int i; 692 709 for (i = 0; i < g_list_length(sd->body); i++) { … … 1026 1043 } 1027 1044 if (!strcmp(info, "STATUS MULTI_SUBSCRIBED")) { 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); 1045 skype_chat_get_or_create(ic, id); 1035 1046 } else if (!strcmp(info, "STATUS DIALOG") && sd->groupchat_with) { 1036 gc = imcb_chat_new(ic, id); 1037 imcb_chat_name_hint(gc, id); 1047 gc = skype_chat_get_or_create(ic, id); 1038 1048 /* According to the docs this 1039 1049 * is necessary. However it … … 1046 1056 sd->groupchat_with); 1047 1057 imcb_chat_add_buddy(gc, buf); 1048 imcb_chat_add_buddy(gc, sd->username);1049 1058 g_free(sd->groupchat_with); 1050 1059 sd->groupchat_with = NULL; 1051 skype_printf(ic, "GET CHAT %s ADDER\n", id);1052 skype_printf(ic, "GET CHAT %s TOPIC\n", id);1053 1060 } else if (!strcmp(info, "STATUS UNSUBSCRIBED")) { 1054 1061 gc = bee_chat_by_title(ic->bee, ic, id); … … 1257 1264 } 1258 1265 g_strfreev(lines); 1259 } else if (st == 0 || (st < 0 && !s ockerr_again())) {1266 } else if (st == 0 || (st < 0 && !ssl_sockerr_again(sd->ssl))) { 1260 1267 ssl_disconnect(sd->ssl); 1261 1268 sd->fd = -1; -
protocols/skype/t/add-yes-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/added-no-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/added-yes-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/away-set-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/call-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :alice -
protocols/skype/t/call-failed-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :alice -
protocols/skype/t/called-no-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/called-yes-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/ctcp-help-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/filetransfer-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/group-add-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/group-read-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/groupchat-invite-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 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 0 :@alice bob@root10 << INVITE cecil ##alice/$bob;a7ab206ec78 011 >> cecil@skype.com JOIN :##alice/$bob;a7ab206ec78 09 >> 353 alice = ##alice/$bob;a7ab206ec78 :@alice @root 10 << INVITE cecil ##alice/$bob;a7ab206ec78 11 >> cecil@skype.com JOIN :##alice/$bob;a7ab206ec78 -
protocols/skype/t/groupchat-invite-skyped.mock
re4f08bf r29ff5c2 26 26 >> GET CHAT #alice/$bob;a7ab206ec78060f1 TOPIC 27 27 << CHAT #alice/$bob;a7ab206ec78060f1 TOPIC 28 >> GET CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS 29 << CHAT #alice/$bob;a7ab206ec78060f1 ACTIVEMEMBERS 28 30 << CHATMESSAGE 206 STATUS SENDING 29 31 << CHAT #alice/$bob;a7ab206ec78060f1 STATUS DIALOG -
protocols/skype/t/groupchat-invited-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 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 18 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root7 >> JOIN :##cecil/$bob;4d8cc996579 8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root -
protocols/skype/t/groupchat-leave-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 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 19 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root10 << PART ##cecil/$bob;4d8cc996579 18 >> JOIN :##cecil/$bob;4d8cc996579 9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root 10 << PART ##cecil/$bob;4d8cc996579 11 11 >> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 STATUS UNSUBSCRIBED -
protocols/skype/t/groupchat-leave-skyped.mock
re4f08bf r29ff5c2 36 36 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 37 37 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 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 38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS 39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS 46 40 >> GET CHATMESSAGE 188 FROM_HANDLE 47 41 << CHATMESSAGE 188 FROM_HANDLE bob -
protocols/skype/t/groupchat-msg-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 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 19 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root10 << PRIVMSG ##cecil/$bob;4d8cc996579 1:hello8 >> JOIN :##cecil/$bob;4d8cc996579 9 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root 10 << PRIVMSG ##cecil/$bob;4d8cc996579 :hello 11 11 >> PRIVMSG &bitlbee :alice: CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVITY_TIMESTAMP -
protocols/skype/t/groupchat-msg-skyped.mock
re4f08bf r29ff5c2 36 36 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 37 37 << CHAT #cecil/$bob;4d8cc9965791c6b9 TOPIC 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 38 >> GET CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS 39 << CHAT #cecil/$bob;4d8cc9965791c6b9 ACTIVEMEMBERS bob cecil alice 46 40 >> GET CHATMESSAGE 188 FROM_HANDLE 47 41 << CHATMESSAGE 188 FROM_HANDLE bob -
protocols/skype/t/groupchat-topic-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 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 18 >> 353 alice = ##cecil/$bob;4d8cc996579 1 :@alice bob cecil@root9 << TOPIC ##cecil/$bob;4d8cc996579 1:topic10 >> TOPIC ##cecil/$bob;4d8cc996579 1:topic7 >> JOIN :##cecil/$bob;4d8cc996579 8 >> 353 alice = ##cecil/$bob;4d8cc996579 :@alice @root 9 << TOPIC ##cecil/$bob;4d8cc996579 :topic 10 >> TOPIC ##cecil/$bob;4d8cc996579 :topic -
protocols/skype/t/info-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/login-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/msg-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/skype/t/set-mood-text-bitlbee.mock
re4f08bf r29ff5c2 1 >> NOTICE AUTH1 >> NOTICE * 2 2 << NICK alice 3 3 << USER alice alice localhost :Alice -
protocols/twitter/twitter.c
re4f08bf r29ff5c2 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 687 680 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); … … 1012 1012 twitter_log(ic, "Tweet `%s' does not exist", cmd[1]); 1013 1013 } else { 1014 /* More common link is twitter.com/$UID/status/$ID (and that's 1015 * what this will 302 to) but can't generate that since for RTs, 1016 * bu here points at the retweeter while id contains the id of 1017 * the original message. */ 1018 twitter_log(ic, "https://twitter.com/statuses/%lld", id); 1014 twitter_status_show_url(ic, id); 1019 1015 } 1020 1016 goto eof; -
protocols/twitter/twitter_http.c
re4f08bf r29ff5c2 24 24 /***************************************************************************\ 25 25 * * 26 * Some fun tions within this file have been copied from other files within *26 * Some functions 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 ;55 void *ret = NULL; 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 g_free(base_url); 75 return NULL; 74 goto error; 76 75 } 77 76 } … … 132 131 } 133 132 133 error: 134 134 g_free(url_arguments); 135 135 g_string_free(request, TRUE); -
protocols/twitter/twitter_lib.c
re4f08bf r29ff5c2 312 312 td = ic->proto_data; 313 313 314 // Parse the data. 315 if (!(parsed = twitter_parse_response(ic, req))) { 316 return; 317 } 318 314 319 txl = g_new0(struct twitter_xml_list, 1); 315 320 txl->list = td->follow_ids; 316 317 // Parse the data.318 if (!(parsed = twitter_parse_response(ic, req))) {319 return;320 }321 321 322 322 twitter_xt_get_friends_id_list(parsed, txl); … … 388 388 } 389 389 390 // Get the user list from the parsed xml feed. 391 if (!(parsed = twitter_parse_response(ic, req))) { 392 return; 393 } 394 390 395 txl = g_new0(struct twitter_xml_list, 1); 391 396 txl->list = NULL; 392 397 393 // Get the user list from the parsed xml feed.394 if (!(parsed = twitter_parse_response(ic, req))) {395 return;396 }397 398 twitter_xt_get_users(parsed, txl); 398 399 json_value_free(parsed); … … 1385 1386 td = ic->proto_data; 1386 1387 1387 txl = g_new0(struct twitter_xml_list, 1);1388 txl->list = NULL;1389 1390 1388 // The root <statuses> node should hold the list of statuses <status> 1391 1389 if (!(parsed = twitter_parse_response(ic, req))) { 1392 1390 goto end; 1393 1391 } 1392 1393 txl = g_new0(struct twitter_xml_list, 1); 1394 txl->list = NULL; 1395 1394 1396 twitter_xt_get_status_list(ic, parsed, txl); 1395 1397 json_value_free(parsed); … … 1424 1426 td = ic->proto_data; 1425 1427 1426 txl = g_new0(struct twitter_xml_list, 1);1427 txl->list = NULL;1428 1429 1428 // The root <statuses> node should hold the list of statuses <status> 1430 1429 if (!(parsed = twitter_parse_response(ic, req))) { 1431 1430 goto end; 1432 1431 } 1432 1433 txl = g_new0(struct twitter_xml_list, 1); 1434 txl->list = NULL; 1435 1433 1436 twitter_xt_get_status_list(ic, parsed, txl); 1434 1437 json_value_free(parsed); … … 1573 1576 g_free(args[1]); 1574 1577 } 1578 1579 static void twitter_http_status_show_url(struct http_request *req) 1580 { 1581 struct im_connection *ic = req->data; 1582 json_value *parsed, *id; 1583 const char *name; 1584 1585 // Check if the connection is still active. 1586 if (!g_slist_find(twitter_connections, ic)) { 1587 return; 1588 } 1589 1590 if (!(parsed = twitter_parse_response(ic, req))) { 1591 return; 1592 } 1593 1594 /* for the parson branch: 1595 name = json_object_dotget_string(json_object(parsed), "user.screen_name"); 1596 id = json_object_get_integer(json_object(parsed), "id"); 1597 */ 1598 1599 name = json_o_str(json_o_get(parsed, "user"), "screen_name"); 1600 id = json_o_get(parsed, "id"); 1601 1602 if (name && id && id->type == json_integer) { 1603 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer); 1604 } else { 1605 twitter_log(ic, "Error: could not fetch tweet url."); 1606 } 1607 1608 json_value_free(parsed); 1609 } 1610 1611 void twitter_status_show_url(struct im_connection *ic, guint64 id) 1612 { 1613 char *url = g_strdup_printf("%s%" G_GUINT64_FORMAT "%s", TWITTER_STATUS_SHOW_URL, id, ".json"); 1614 twitter_http(ic, url, twitter_http_status_show_url, ic, 0, NULL, 0); 1615 g_free(url); 1616 } -
protocols/twitter/twitter_lib.h
re4f08bf r29ff5c2 96 96 void twitter_report_spam(struct im_connection *ic, char *screen_name); 97 97 void twitter_favourite_tweet(struct im_connection *ic, guint64 id); 98 void twitter_status_show_url(struct im_connection *ic, guint64 id); 98 99 99 100 #endif //_TWITTER_LIB_H -
protocols/yahoo/libyahoo2.c
re4f08bf r29ff5c2 12 12 * GNU GPL. 13 13 * 14 * This code is deriv itive of Gaim <http://gaim.sourceforge.net>14 * This code is derivative 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 cross multiple packets and not1404 * Status updates may be spread across 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
re4f08bf r29ff5c2 440 440 { 441 441 struct byahoo_connect_callback_data *d = data; 442 443 if (!byahoo_get_ic_by_id(d->id)) { 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); 444 453 g_free(d); 445 454 return; -
protocols/yahoo/yahoo2_callbacks.h
re4f08bf r29ff5c2 685 685 * Name: ext_yahoo_connect_async 686 686 * Connect to a host:port asynchronously. This function should return 687 * immediately retur ing a tag used to identify the connection handler,687 * immediately returning 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
re4f08bf r29ff5c2 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 165 171 bitlbee_whatsnew(irc); 166 172 … … 238 244 irc->status |= USTATUS_IDENTIFIED; 239 245 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 } 240 252 241 253 /* Set this var now, or anyone who logs in to his/her -
tests/Makefile
re4f08bf r29ff5c2 15 15 distclean: clean 16 16 17 main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_c hannel.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_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o 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
re4f08bf r29ff5c2 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 */ 44 49 } 45 50 -
tests/check_jabber_util.c
re4f08bf r29ff5c2 37 37 fail_unless(jabber_buddy_by_jid(ic, "wilmer@GAAST.NET/BitlBee", GET_BUDDY_CREAT) == budw1); 38 38 39 fail_ if(jabber_buddy_by_jid(ic, "wilmer@gaast.net", GET_BUDDY_EXACT));39 fail_unless(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 -
tests/check_user.c
re4f08bf r29ff5c2 46 46 END_TEST 47 47 48 START_TEST(test_user_del_nonexist ant)48 START_TEST(test_user_del_nonexistent) 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 ant);73 tcase_add_test(tc_core, test_user_del_nonexistent); 74 74 tcase_add_test(tc_core, test_user_del); 75 75 tcase_add_test(tc_core, test_user_rename); -
unix.c
re4f08bf r29ff5c2 48 48 global_t global; /* Against global namespace pollution */ 49 49 50 static int signal_shutdown_pipe[2] = { -1, -1 }; 50 static struct { 51 int fd[2]; 52 int tag; 53 } shutdown_pipe = {{-1 , -1}, 0}; 54 51 55 static void sighandler_shutdown(int signal); 52 56 static void sighandler_crash(int signal); … … 156 160 sigaction(SIGSEGV, &sig, &old); 157 161 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 } 162 sighandler_shutdown_setup(); 163 164 sig.sa_handler = sighandler_shutdown; 165 sigaction(SIGINT, &sig, &old); 166 sigaction(SIGTERM, &sig, &old); 165 167 166 168 if (!getuid() || !geteuid()) { … … 256 258 } 257 259 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 258 275 /* Signal handler for SIGTERM and SIGINT */ 259 276 static void sighandler_shutdown(int signal) … … 261 278 /* Write a single null byte to the pipe, just to send a message to the main loop. 262 279 * This gets handled by bitlbee_shutdown (the b_input_add callback for this pipe) */ 263 write(s ignal_shutdown_pipe[1], "", 1);280 write(shutdown_pipe.fd[1], "", 1); 264 281 } 265 282 … … 275 292 for (l = irc_connection_list; l; l = l->next) { 276 293 irc_t *irc = l->data; 294 sock_make_blocking(irc->fd); 277 295 write(irc->fd, message, len); 278 296 }
Note: See TracChangeset
for help on using the changeset viewer.