Changes in / [eb0714d:9b55485]
- Files:
-
- 7 added
- 2 deleted
- 79 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
reb0714d r9b55485 17 17 *.gcno 18 18 *.o 19 coverage 20 bitlbee.info 21 bitlbee.exe -
Makefile
reb0714d r9b55485 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o c onf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o otr.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.ouser.o12 objects = account.o bitlbee.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o 13 13 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h otr.h query.h set.h sock.h storage.h user.h lib/events.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h 14 14 subdirs = lib protocols 15 16 ifeq ($(TARGET),i586-mingw32msvc) 17 objects += win32.o 18 LFLAGS+=-lws2_32 19 EFLAGS+=-lsecur32 20 OUTFILE=bitlbee.exe 21 else 22 objects += unix.o conf.o log.o otr.o 23 OUTFILE=bitlbee 24 endif 15 25 16 26 # Expansion of variables -
account.c
reb0714d r9b55485 182 182 account_t *a, *l = NULL; 183 183 184 if( acc->ic ) 185 /* Caller should have checked, accounts still in use can't be deleted. */ 186 return; 187 184 188 for( a = irc->accounts; a; a = (l=a)->next ) 185 189 if( a == acc ) 186 190 { 187 if( a->ic ) return; /* Caller should have checked, accounts still in use can't be deleted. */188 189 191 if( l ) 190 {191 192 l->next = a->next; 192 }193 193 else 194 {195 194 irc->accounts = a->next; 196 }197 195 198 196 while( a->set ) … … 203 201 g_free( a->user ); 204 202 g_free( a->pass ); 205 if( a->server )g_free( a->server );203 g_free( a->server ); 206 204 if( a->reconnect ) /* This prevents any reconnect still queued to happen */ 207 205 cancel_auto_reconnect( a ); -
bitlbee.c
reb0714d r9b55485 54 54 ; 55 55 56 i = getaddrinfo( global.conf->iface , global.conf->port, &hints, &addrinfo_bind );56 i = getaddrinfo( global.conf->iface_in, global.conf->port, &hints, &addrinfo_bind ); 57 57 if( i ) 58 58 { 59 59 log_message( LOGLVL_ERROR, "Couldn't parse address `%s': %s", 60 global.conf->iface , gai_strerror(i) );60 global.conf->iface_in, gai_strerror(i) ); 61 61 return -1; 62 62 } … … 118 118 119 119 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 120 ipc_master_load_state( );120 ipc_master_load_state( getenv( "_BITLBEE_RESTART_STATE" ) ); 121 121 122 122 if( global.conf->runmode == RUNMODE_DAEMON || global.conf->runmode == RUNMODE_FORKDAEMON ) 123 123 ipc_master_listen_socket(); 124 124 125 #ifndef _WIN32 125 126 if( ( fp = fopen( global.conf->pidfile, "w" ) ) ) 126 127 { … … 132 133 log_message( LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile ); 133 134 } 135 #endif 134 136 135 137 return( 0 ); … … 140 142 if( !irc_new( 0 ) ) 141 143 return( 1 ); 142 143 log_link( LOGLVL_ERROR, LOGOUTPUT_IRC );144 log_link( LOGLVL_WARNING, LOGOUTPUT_IRC );145 144 146 145 return( 0 ); … … 226 225 if( st == size ) 227 226 { 228 g_free( irc->sendbuffer );229 irc->sendbuffer = NULL;230 irc->w_watch_source_id = 0;231 232 227 if( irc->status & USTATUS_SHUTDOWN ) 228 { 233 229 irc_free( irc ); 230 } 231 else 232 { 233 g_free( irc->sendbuffer ); 234 irc->sendbuffer = NULL; 235 irc->w_watch_source_id = 0; 236 } 234 237 235 238 return FALSE; … … 250 253 struct sockaddr_in conn_info; 251 254 int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size ); 252 pid_t client_pid = 0;253 255 254 256 if( new_socket == -1 ) … … 258 260 } 259 261 262 #ifndef _WIN32 260 263 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 261 264 { 265 pid_t client_pid = 0; 262 266 int fds[2]; 263 267 … … 316 320 } 317 321 else 322 #endif 318 323 { 319 324 log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket ); -
bitlbee.conf
reb0714d r9b55485 10 10 ## 11 11 ## Inetd -- Run from inetd (default) 12 ## Daemon -- Run as a stand-alone daemon -- EXPERIMENTAL! BitlBee is not yet 13 ## stable enough to serve lots of users from one process. Because of this 14 ## and other reasons, the use of daemon-mode is *STRONGLY* discouraged, 15 ## don't even *think* of reporting bugs when you use this. 12 ## Daemon -- Run as a stand-alone daemon, serving all users from one process. 13 ## This saves memory if there are more users, the downside is that when one 14 ## user hits a crash-bug, all other users will also lose their connection. 16 15 ## ForkDaemon -- Run as a stand-alone daemon, but keep all clients in separate 17 16 ## child processes. This should be pretty safe and reliable to use instead … … 35 34 # DaemonPort = 6667 36 35 36 ## ClientInterface: 37 ## 38 ## If for any reason, you want BitlBee to use a specific address/interface 39 ## for outgoing traffic (IM connections, HTTP(S), etc.), set it here. 40 ## 41 # ClientInterface = 0.0.0.0 42 37 43 ## AuthMode 38 44 ## … … 49 55 ## 50 56 ## Password the user should enter when logging into a closed BitlBee server. 57 ## You can also have an MD5-encrypted password here. Format: "md5:", followed 58 ## by a hash as generated for the <user password=""> attribute in a BitlBee 59 ## XML file (for now there's no easier way to generate the hash). 51 60 ## 52 61 # AuthPassword = ItllBeBitlBee ## Heh.. Our slogan. ;-) 62 ## or 63 # AuthPassword = md5:gzkK0Ox/1xh+1XTsQjXxBJ571Vgl 53 64 54 65 ## OperPassword … … 57 68 ## 58 69 # OperPassword = ChangeMe! 70 ## or 71 # OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX 59 72 60 73 ## HostName -
bitlbee.h
reb0714d r9b55485 29 29 #define _GNU_SOURCE /* Stupid GNU :-P */ 30 30 31 /* Depend on Windows 2000 for now since we need getaddrinfo() */ 32 #define _WIN32_WINNT 0x0501 33 31 34 #define PACKAGE "BitlBee" 32 #define BITLBEE_VERSION "1. 1.1dev"35 #define BITLBEE_VERSION "1.2.1" 33 36 #define VERSION BITLBEE_VERSION 34 37 35 #define MAX_STRING 12838 #define MAX_STRING 511 36 39 37 40 #if HAVE_CONFIG_H … … 48 51 #include <stdio.h> 49 52 #include <ctype.h> 53 #include <errno.h> 54 50 55 #ifndef _WIN32 51 56 #include <syslog.h> 52 #include <errno.h>53 57 #endif 54 58 … … 94 98 #undef g_main_quit 95 99 #define g_main_quit __PLEASE_USE_B_MAIN_QUIT__ 96 97 #ifndef F_OK98 #define F_OK 099 #endif100 100 101 101 #ifndef G_GNUC_MALLOC … … 162 162 gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ); 163 163 164 char *set_eval_root_nick( set_t *set, char *new_nick ); 165 164 166 extern global_t global; 165 167 -
conf.c
reb0714d r9b55485 45 45 conf = g_new0( conf_t, 1 ); 46 46 47 conf->iface = NULL; 47 conf->iface_in = NULL; 48 conf->iface_out = NULL; 48 49 conf->port = g_strdup( "6667" ); 49 50 conf->nofork = 0; … … 78 79 } 79 80 80 while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:h R:u:" ) ) >= 0 )81 while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hu:" ) ) >= 0 ) 81 82 /* ^^^^ Just to make sure we skip this step from the REHASH handler. */ 82 83 { 83 84 if( opt == 'i' ) 84 85 { 85 conf->iface = g_strdup( optarg );86 conf->iface_in = g_strdup( optarg ); 86 87 } 87 88 else if( opt == 'p' ) … … 132 133 "\n" 133 134 " -I Classic/InetD mode. (Default)\n" 134 " -D Daemon mode. ( Still EXPERIMENTAL!)\n"135 " -D Daemon mode. (one process serves all)\n" 135 136 " -F Forking daemon. (one process per client)\n" 136 137 " -u Run daemon as specified user.\n" … … 146 147 return NULL; 147 148 } 148 else if( opt == 'R' )149 {150 /* We can't load the statefile yet (and should make very sure we do this151 only once), so set the filename here and load the state information152 when initializing ForkDaemon. (This option only makes sense in that153 mode anyway!) */154 ipc_master_set_statefile( optarg );155 }156 149 else if( opt == 'u' ) 157 150 { … … 203 196 else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 ) 204 197 { 205 g_free( conf->iface );206 conf->iface = g_strdup( ini->value );198 g_free( conf->iface_in ); 199 conf->iface_in = g_strdup( ini->value ); 207 200 } 208 201 else if( g_strcasecmp( ini->key, "daemonport" ) == 0 ) … … 210 203 g_free( conf->port ); 211 204 conf->port = g_strdup( ini->value ); 205 } 206 else if( g_strcasecmp( ini->key, "clientinterface" ) == 0 ) 207 { 208 g_free( conf->iface_out ); 209 conf->iface_out = g_strdup( ini->value ); 212 210 } 213 211 else if( g_strcasecmp( ini->key, "authmode" ) == 0 ) … … 258 256 { 259 257 g_strfreev( conf->migrate_storage ); 260 conf->migrate_storage = g_strsplit ( ini->value, " \t,;", -1 );258 conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 ); 261 259 } 262 260 else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 ) -
conf.h
reb0714d r9b55485 32 32 typedef struct conf 33 33 { 34 char *iface ;34 char *iface_in, *iface_out; 35 35 char *port; 36 36 int nofork; -
configure
reb0714d r9b55485 20 20 ipcsocket='/var/run/bitlbee.sock' 21 21 pcdir='$prefix/lib/pkgconfig' 22 systemlibdirs="/lib /usr/lib /usr/local/lib" 22 23 23 24 msn=1 … … 76 77 --ssl=... SSL library to use (gnutls, nss, openssl, bogus, auto) 77 78 $ssl 79 80 --target=... Cross compilation target same as host 78 81 EOF 79 82 exit; … … 109 112 PCDIR=$pcdir 110 113 114 TARGET=$target 111 115 ARCH=$arch 112 116 CPU=$cpu 113 OUTFILE=bitlbee114 117 115 118 DESTDIR= … … 134 137 EOF 135 138 139 140 141 if [ -n "$target" ]; then 142 PKG_CONFIG_LIBDIR=/usr/$target/lib/pkgconfig 143 export PKG_CONFIG_LIBDIR 144 PATH=/usr/$target/bin:$PATH 145 CC=$target-cc 146 LD=$target-ld 147 systemlibdirs="/usr/$target/lib" 148 fi 149 150 136 151 if [ "$debug" = "1" ]; then 137 152 [ -z "$CFLAGS" ] && CFLAGS=-g … … 160 175 echo "CC=$CC" >> Makefile.settings; 161 176 162 if [ -n "$LD" ]; then 163 echo "LD=$LD" >> Makefile.settings; 164 elif type ld > /dev/null 2> /dev/null; then 165 echo "LD=ld" >> Makefile.settings; 166 else 167 echo 'Cannot find ld, aborting.' 168 exit 1; 169 fi 177 if [ -z "$LD" ]; then 178 if type ld > /dev/null 2> /dev/null; then 179 LD=ld 180 else 181 echo 'Cannot find ld, aborting.' 182 exit 1; 183 fi 184 fi 185 186 echo "LD=$LD" >> Makefile.settings 170 187 171 188 if [ -z "$PKG_CONFIG" ]; then … … 215 232 detect_gnutls() 216 233 { 217 if libgnutls-config --version > /dev/null 2> /dev/null; then 234 if $PKG_CONFIG --exists gnutls; then 235 cat <<EOF>>Makefile.settings 236 EFLAGS+=`$PKG_CONFIG --libs gnutls` 237 CFLAGS+=`$PKG_CONFIG --cflags gnutls` 238 EOF 239 ssl=gnutls 240 ret=1 241 elif libgnutls-config --version > /dev/null 2> /dev/null; then 218 242 cat <<EOF>>Makefile.settings 219 243 EFLAGS+=`libgnutls-config --libs` … … 269 293 elif [ "$ssl" = "nss" ]; then 270 294 detect_nss 295 elif [ "$ssl" = "sspi" ]; then 296 echo 271 297 elif [ "$ssl" = "openssl" ]; then 272 298 echo … … 325 351 echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings 326 352 327 for i in /lib /usr/lib /usr/local/lib; do353 for i in $systemlibdirs; do 328 354 if [ -f $i/libresolv.a ]; then 329 355 echo '#define HAVE_RESOLV_A' >> config.h … … 377 403 378 404 if [ "$gcov" = "1" ]; then 379 echo "CFLAGS+=- ftest-coverage -fprofile-arcs" >> Makefile.settings380 echo "EFLAGS+=- lgcov" >> Makefile.settings405 echo "CFLAGS+=--coverage" >> Makefile.settings 406 echo "EFLAGS+=--coverage" >> Makefile.settings 381 407 fi 382 408 … … 387 413 fi 388 414 415 otrprefix="" 416 for i in / /usr /usr/local; do 417 if [ -f ${i}/lib/libotr.a ]; then 418 otrprefix=${i} 419 break 420 fi 421 done 389 422 if [ "$otr" = "auto" ]; then 390 for i in /lib /usr/lib /usr/local/lib; do 391 if [ -f $i/libotr.a ]; then 392 otr=1 393 break 394 fi 395 done 396 fi 397 if [ "$otr" = 0 ]; then 423 if [ -n "$otrprefix" ]; then 424 otr=1 425 else 426 otr=0 427 fi 428 fi 429 if [ "$otr" = 1 ]; then 430 echo '#define WITH_OTR' >> config.h 431 echo "EFLAGS+=-L${otrprefix}/lib -lotr" >> Makefile.settings 432 echo "CFLAGS+=-I${otrprefix}/include" >> Makefile.settings 433 else 398 434 echo '#undef WITH_OTR' >> config.h 399 else400 echo '#define WITH_OTR' >> config.h401 echo "EFLAGS+=-lotr" >> Makefile.settings402 435 fi 403 436 … … 500 533 echo 'Cygwin is not officially supported.' 501 534 ;; 535 Windows ) 536 ;; 502 537 * ) 503 538 echo 'We haven'\''t tested BitlBee on many platforms yet, yours is untested. YMMV.' … … 506 541 esac 507 542 543 if [ -n "$target" ]; then 544 echo "Cross-compiling for: $target" 545 fi 546 508 547 echo 509 548 echo 'Configuration done:' -
debian/README.Debian
reb0714d r9b55485 1 *** NEWS (Version 1. 1and later) ***1 *** NEWS (Version 1.2 and later) *** 2 2 3 Starting from version 1. 1, BitlBee has a forking daemon mode. The Debian3 Starting from version 1.2, BitlBee has a forking daemon mode. The Debian 4 4 package now uses this mode by default, instead of inetd mode. If you don't 5 5 want to use this, you can disable the init scripts (best way to do this is … … 7 7 should be necessary only once, it won't be touched during upgrades. 8 8 9 -------------------------------------------------------------------------- 9 Another important change in BitlBee 1.2 is the file format used for your 10 personal settings. Everything's now saved in a single .xml (per account, 11 of course) file instead of $nick.accounts and $nick.nicks. One advantage 12 of this new format is that the passwords are actually encrypted instead of 13 just vaguely obfuscated. BitlBee can still read the old files, and will 14 save things in the new format when you save/disconnect. After that, you 15 can safely remove the old-style files (this is recommended). 16 17 I tried making this transition (the new file format but especially, in this 18 case, the inetd->forkdaemon mode change) as smooth as possible, but I'm 19 aware that many BitlBee users will have their own hacks already to run the 20 program. I hope the package won't break any of this for anyone. 1.2-2 21 should fix at least some of the issues. 22 23 --------------------------------------------------------------------------- 10 24 11 25 Debconf should have asked you on what port you want BitlBee to run. If it -
debian/bitlbee.init
reb0714d r9b55485 1 1 #! /bin/sh 2 ### BEGIN INIT INFO 3 # Provides: bitlbee 4 # Required-Start: $remote_fs $syslog 5 # Required-Stop: $remote_fs $syslog 6 # Default-Start: 2 3 4 5 7 # Default-Stop: 1 8 ### END INIT INFO 2 9 # 3 10 # Init script for BitlBee Debian package. Based on skeleton init script: … … 18 25 # Default value 19 26 BITLBEE_PORT=6667 20 DAEMON_OPT=-F27 BITLBEE_OPTS=-F 21 28 22 29 # Read config file if it is present. … … 37 44 38 45 start-stop-daemon --start --quiet --pidfile $PIDFILE \ 39 -c bitlbee -g nogroup \ 40 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $DAEMON_OPT 46 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS 41 47 } 42 48 -
debian/changelog
reb0714d r9b55485 1 bitlbee (1.1.1dev-0pre) unstable; urgency=low 2 1 bitlbee (1.2-6) UNRELEASED; urgency=low 2 3 * Add Homepage and Vcs-Bzr fields. 4 5 -- Jelmer Vernooij <jelmer@samba.org> Sun, 11 May 2008 14:18:16 +0200 6 7 bitlbee (1.2-5) unstable; urgency=low 8 9 * Add myself to uploaders. 10 * Bump standards version to 3.8.0. 11 * Fix FSF address. 12 * Avoid changing uid from init script. (Closes: #474589) 13 14 -- Jelmer Vernooij <jelmer@samba.org> Mon, 16 Jun 2008 00:53:20 +0200 15 16 bitlbee (1.2-4) unstable; urgency=low 17 18 * Fixed init script to use the BITLBEE_OPTS variable, not an undefined 19 DAEMON_OPT. (Closes: #474583) 20 * Added dependency information to the init script. (Closes: #472567) 21 * Added bitlbee-dev package. Patch from RISKO Gergely <risko@debian.org> 22 with some small modifications. (Closes: #473480) 23 24 -- Wilmer van der Gaast <wilmer@gaast.net> Wed, 07 May 2008 22:40:40 -0700 25 26 bitlbee (1.2-3) unstable; urgency=low 27 28 * Removed DEB_BUILD_OPTIONS again (forgot to apply that change to the 1.2 29 branch when I finished 1.0.4-2, things diverged too much anyway.) 30 Closes: #472540. 31 32 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 24 Mar 2008 21:10:14 +0000 33 34 bitlbee (1.2-2) unstable; urgency=low 35 36 * Fixed some packaging issues reported by IRC and e-mail. (Closes: #472373) 37 * Fixed proxy support. (Closes: #472395) 38 * Added a BitlBee group so only root can edit the configs and BitlBee can 39 just *read* it. 40 * Manually deleting /var/lib/bitlbee/ when purging, deluser doesn't want to 41 do it. 42 43 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 24 Mar 2008 19:48:24 +0000 44 45 bitlbee (1.2-1) unstable; urgency=low 46 47 * New upstream release. (Closes: #325017, #386914, #437515) 48 * With hopefully completely sane charset handling (Closes: #296145) 3 49 * Switched to the new forking daemon mode. Added /etc/default/bitlbee 4 50 file, an init script. People who want to stick with inetd can do so, see 5 51 the defaults file. 52 (Closes: #460741, #466171, #294585, #345038, #306452, #392682) 6 53 * Got rid of debconf Woody compatibility stuff. 7 54 * No more MPL code in BitlBee, thanks to the Jabber module rewrite! 8 9 -- Wilmer van der Gaast <wilmer@gaast.net> Fri, 06 Jul 2007 09:09:36 +0100 55 * Added Italian translation, sorry for taking so long! (Closes: #448238) 56 * Added libevent dependency (more reliable event handling). 57 * Removed GLib 1.x dependency because BitlBee really requires GLib >=2.4. 58 59 -- Wilmer van der Gaast <wilmer@gaast.net> Tue, 18 Mar 2008 23:44:19 +0000 60 61 bitlbee (1.0.4-2) unstable; urgency=low 62 63 * Removed $DEB_BUILD_OPTIONS because apparently buildds fill it with crap. 64 (Closes: #458717) 65 66 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 11 Feb 2008 19:15:33 +0000 67 68 bitlbee (1.0.4-1) unstable; urgency=low 69 70 * New upstream release. 71 * Changed libnss-dev dependency. (Closes: #370442) 72 * Added build-indep rule to debian/rules. (Closes: #395673) 73 74 -- Wilmer van der Gaast <wilmer@gaast.net> Wed, 29 Aug 2007 20:24:28 +0100 10 75 11 76 bitlbee (1.0.3-1.3) unstable; urgency=low -
debian/conffiles
reb0714d r9b55485 1 1 /etc/bitlbee/motd.txt 2 2 /etc/bitlbee/bitlbee.conf 3 /etc/init.d/bitlbee -
debian/control
reb0714d r9b55485 3 3 Priority: optional 4 4 Maintainer: Wilmer van der Gaast <wilmer@gaast.net> 5 Standards-Version: 3.5.9 6 Build-Depends: libglib2.0-dev | libglib-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf 5 Uploaders: Jelmer Vernooij <jelmer@samba.org> 6 Standards-Version: 3.8.0 7 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf 8 Homepage: http://www.bitlbee.org/ 9 Vcs-Bzr: http://code.bitlbee.org/bitlbee/ 10 DM-Upload-Allowed: yes 7 11 8 12 Package: bitlbee … … 12 16 This program can be used as an IRC server which forwards everything you 13 17 say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo. 18 19 Package: bitlbee-dev 20 Architecture: all 21 Depends: bitlbee (= ${binary:Version}) 22 Description: An IRC to other chat networks gateway 23 This program can be used as an IRC server which forwards everything you 24 say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo. 25 . 26 This package holds development stuff for compiling plug-ins. -
debian/copyright
reb0714d r9b55485 26 26 You should have received a copy of the GNU General Public License with 27 27 the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL; 28 if not, write to the Free Software Foundation, Inc., 5 9 Temple Place,29 Suite 330, Boston, MA 02111-1307 USA28 if not, write to the Free Software Foundation, Inc., 51 Franklin St, 29 Fifth Floor, Boston, MA 02110-1301, USA. 30 30 ============================================================================ 31 31 … … 40 40 41 41 Copyright (C) 2000 Free Software Foundation, Inc. 42 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA42 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 43 43 Everyone is permitted to copy and distribute verbatim copies 44 44 of this license document, but changing it is not allowed. -
debian/postinst
reb0714d r9b55485 14 14 BITLBEE_DISABLED=0 15 15 BITLBEE_UPGRADE_DONT_RESTART=0 16 [ -r /etc/default/bitlbee ] && source/etc/default/bitlbee16 [ -r /etc/default/bitlbee ] && . /etc/default/bitlbee 17 17 18 if [ "$BITLBEE_DISABLED" = "0" ]; then 19 ## In case it's still there (if we're upgrading right now) 18 if [ "$BITLBEE_DISABLED" = "0" ] && type update-inetd > /dev/null 2> /dev/null && 19 ( expr "$2" : '0\..*' > /dev/null || expr "$2" : '1\.0\..*' > /dev/null ); then 20 ## Make sure the inetd entry is gone (can still be there from a 21 ## previous version. 20 22 update-inetd --remove '.*/usr/sbin/bitlbee' 23 if grep -q /usr/sbin/bitlbee /etc/inetd.conf 2> /dev/null; then 24 # Thanks for breaking update-inetd! (bugs.debian.org/311111) 25 # I hope that it works at least with xinetd, because this 26 # emergency hack doesn't: 27 perl -pi -e 's:^[^#].*/usr/sbin/bitlbee$:## Now using daemon mode\: # $&:' /etc/inetd.conf 28 killall -HUP inetd || true 29 fi 21 30 fi 22 31 … … 65 74 fi 66 75 67 adduser --system -- home /var/lib/bitlbee/ --disabled-login --disabled-passwordbitlbee76 adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee 68 77 chmod 700 /var/lib/bitlbee/ 69 78 70 79 ## Can't do this in packaging phase: Don't know the UID yet. Access to 71 ## the file should be limited, now that it stores passwords. 72 chmod 600 /etc/bitlbee/bitlbee.conf 73 chown bitlbee /etc/bitlbee/bitlbee.conf 80 ## the file should be limited, now that it stores passwords. Added 81 ## --group later for a little more security, but have to see if I can 82 ## apply this change to existing installations on upgrades. Will think 83 ## about that later. 84 if getent group bitlbee > /dev/null; then 85 chmod 640 /etc/bitlbee/bitlbee.conf 86 chown root:bitlbee /etc/bitlbee/bitlbee.conf 87 else 88 chmod 600 /etc/bitlbee/bitlbee.conf 89 chown bitlbee /etc/bitlbee/bitlbee.conf 90 fi 74 91 75 92 if [ -z "$2" ]; then -
debian/postrm
reb0714d r9b55485 9 9 10 10 update-rc.d bitlbee remove > /dev/null 2>&1 || true 11 deluser --remove-home bitlbee || true 11 rm -f /etc/default/bitlbee 12 13 deluser --system --remove-home bitlbee || true 14 rm -rf /var/lib/bitlbee ## deluser doesn't seem to do this for homedirs in /var -
debian/rules
reb0714d r9b55485 3 3 DEBUG ?= 0 4 4 5 ifdef BITLBEE_VERSION 6 BITLBEE_FORCE_VERSION=1 7 else 5 8 # Want to use the full package version number instead of just the release. 6 9 BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')" 7 10 export BITLBEE_VERSION 8 11 endif 9 12 10 13 build-arch: build-arch-stamp 11 14 build-arch-stamp: 12 if [ ! -d debian ]; then exit 1; fi13 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee $(DEB_BUILD_OPTIONS)15 [ -d debian ] 16 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent 14 17 $(MAKE) 15 18 # $(MAKE) -C doc/ all … … 17 20 18 21 clean: 19 if [ "`whoami`" != "root" -o ! -d debian ]; then exit 1; fi20 rm -rf build-arch-stamp debian/bitlbee debian/*.substvars debian/files 21 -$(MAKE) distclean22 [ "`whoami`" = "root" -a -d debian ] 23 rm -rf build-arch-stamp debian/bitlbee debian/*.substvars debian/files debian/bitlbee-dev 24 $(MAKE) distclean 22 25 # -$(MAKE) -C doc/ clean 23 26 24 27 25 28 install-arch: build-arch 26 if [ "`whoami`" != "root" -o ! -d debian ]; then exit 1; fi29 [ "`whoami`" = "root" -a -d debian ] 27 30 mkdir -p debian/bitlbee/DEBIAN/ 28 31 $(MAKE) install install-etc DESTDIR=`pwd`/debian/bitlbee … … 32 35 cp doc/user-guide/user-guide.html debian/bitlbee/usr/share/doc/bitlbee/ 33 36 37 install-indep: install-arch 38 [ "`whoami`" = "root" -a -d debian ] 39 mkdir -p debian/bitlbee-dev/DEBIAN/ 40 $(MAKE) install-dev DESTDIR=`pwd`/debian/bitlbee-dev 41 42 mkdir -p debian/bitlbee-dev/usr/share/doc/bitlbee-dev/ 43 34 44 binary-arch: build-arch install-arch 35 if [ "`whoami`" != "root" -o ! -d debian ]; then exit 1; fi45 [ "`whoami`" = "root" -a -d debian ] 36 46 37 47 chmod 755 debian/post* debian/pre* debian/config debian/bitlbee.init … … 49 59 doc/bitlbee/examples/* man/man8/bitlbee.8 man/man5/bitlbee.conf.5 50 60 51 chown -R root .root debian/bitlbee/61 chown -R root:root debian/bitlbee/ 52 62 find debian/bitlbee/usr/share/ -type d -exec chmod 755 {} \; 53 63 find debian/bitlbee/usr/share/ -type f -exec chmod 644 {} \; … … 66 76 find usr -type f -exec md5sum {} \; > DEBIAN/md5sums 67 77 dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee 68 ifdef BITLBEE_ VERSION78 ifdef BITLBEE_FORCE_VERSION 69 79 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee -Tdebian/bitlbee.substvars -Pdebian/bitlbee -v1:$(BITLBEE_VERSION)-0 -V'debconf-depends=debconf (>= 1.2.0) | debconf-2.0' 70 80 else … … 74 84 dpkg --build debian/bitlbee .. 75 85 76 debug-build: 77 BITLBEE_VERSION=\"`date +%Y%m%d`-`hostname`-debug\" debian/rules clean binary DEBUG=186 binary-indep: install-indep 87 [ "`whoami`" = "root" -a -d debian ] 78 88 79 binary: binary-arch 89 chown -R root.root debian/bitlbee-dev/ 90 find debian/bitlbee-dev/usr/share/ -type d -exec chmod 755 {} \; 91 find debian/bitlbee-dev/usr/share/ -type f -exec chmod 644 {} \; 92 93 cp debian/changelog debian/bitlbee-dev/usr/share/doc/bitlbee-dev/changelog.Debian 94 gzip -9 debian/bitlbee-dev/usr/share/doc/bitlbee-dev/changelog.Debian 95 cp debian/copyright debian/bitlbee-dev/usr/share/doc/bitlbee-dev/copyright 96 97 cd debian/bitlbee-dev; \ 98 find usr -type f -exec md5sum {} \; > DEBIAN/md5sums 99 100 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev 101 102 dpkg --build debian/bitlbee-dev .. 103 104 binary: binary-arch binary-indep 80 105 build: build-arch 81 install: install-arch 106 install: install-arch install-indep 82 107 83 .PHONY: build-arch build clean binary-arch binary install-arch install 108 .PHONY: build-arch build clean binary-arch binary install-arch install binary-indep install-indep -
doc/CHANGES
reb0714d r9b55485 1 This ChangeLog mostly lists changes relevant to users. A full log can be 2 found in the bzr commit logs, for example you can try: 3 4 http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on 5 6 Version 1.2.1: 7 - Fixed proxy support. 8 - Fixed stalling issues while connecting to Jabber when using the OpenSSL 9 module. 10 - Fixed problem with GLib and ForkDaemon where processes didn't die when 11 the client disconnects. 12 - Fixed handling of "set charset none". (Which pretty much breaks the account 13 completely in 1.2.) 14 - You can now automatically identify yourself to BitlBee by setting a server 15 password in your IRC client. 16 - Compatible with all crazy kinds of line endings that clients can send. 17 - Changed root nicknames are now saved. 18 - Added ClientInterface setting to bind() outgoing connections to a specific 19 network interface. 20 - Support for receiving Jabber chatroom invitations. 21 - Relaxed port restriction of the Jabber module: added ports 80 and 443. 22 - Preserving case in Jabber resources of buddies, since these should 23 officially be treated as case sensitive. 24 - Fully stripping spaces from AIM screennames, this didn't happen completely 25 which severly breaks the IRC protocol. 26 - Removed all the yellow tape around daemon mode, it's pretty mature by now: 27 testing.bitlbee.org serves all (~30) SSL users from one daemon mode 28 process without any serious stability issues. 29 - Fixed GLib <2.6 compatibility issue. 30 - Misc. memory leak/crash fixes. 31 32 Finished 24 Jun 2008 33 1 34 Version 1.2: 2 - First BitlBee development/testing RELEASE. This should be quite stable3 though (and for most people more stable than 1.0.x). It just has a couple4 of rough edges and needs a bit more testing.5 35 - Added ForkDaemon mode next to the existing Daemon- and inetd modes. With 6 36 ForkDaemon you can run BitlBee as a stand-alone daemon and every connection … … 21 51 1.x is so old that supporting it really isn't necessary anymore. 22 52 - Many, many, MANY little changes, improvements, fixes. Using non-blocking 23 I/O as much as possible, fixed lots of little bugs (including bugs that 24 affected daemon mode stability). See the bzr logs for more information. 25 - Added units tests, will have to add some more before the real release. 53 I/O as much as possible, replaced the Gaim (0.59, IOW heavily outdated) 54 API, fixed lots of little bugs (including bugs that affected daemon mode 55 stability). See the bzr logs for more information. 56 - One of the user-visible changes from the API change: You can finally see 57 all away states/messages properly. 58 - Added units tests. Test coverage is very minimal for now. 59 - Better charset handling: Everything is just converted from/to UTF-8 right 60 in the IRC core, and charset mismatches are detected (if possible) and the 61 user is asked to resolve this before continuing. Also, UTF-8 is the default 62 setting now, since that's how the world seems to work these days. 63 - One can now keep hashed passwords in bitlbee.conf instead of the cleartext 64 version. 26 65 - Most important change: New file format for user data (accounts, nicks and 27 66 settings). Migration to the new format should happen transparently, … … 69 108 * An XML console (add xmlconsole to your contact list or see "help set 70 109 xmlconsole" if you want it permanently). 71 72 Finished ??? 110 - The Yahoo! module now says it supports YMSG protocol version 12, which will 111 hopefully keep the Yahoo module working after 2008-04-02 (when Yahoo! is 112 dropping support for version 6.x of their client). 113 - MSN switchboard handling changes. Hopefully less messages will get lost now, 114 although things are still not perfect. 115 116 Finished 17 Mar 2008 73 117 74 118 Version 1.0.4: -
doc/README
reb0714d r9b55485 41 41 by default) and chown it to the UID BitlBee is running as. Make sure this 42 42 directory is read-/writable by this user only. 43 44 --- (Fork)Daemon mode 45 46 If you don't want to run any inetd daemon, you can run BitlBee in Daemon 47 mode. Right now, daemon mode may be a bad idea on servers with multiple 48 users, since possible fatal BitlBee bugs will crash the BitlBee process and 49 disconnect all connected users at once. Instead, you can use ForkDaemon 50 mode, which serves every user from a separate process, without depending on 51 an inetd daemon. 52 53 To use BitlBee in daemon mode, just start it with the right flags or enable 54 it in bitlbee.conf. You probably want to write an init script to start 55 BitlBee automatically after a reboot. (This is where you realise using 56 a package from your distro would've been a better idea. :-P) 57 58 Note that the BitlBee code is getting stable enough for daemon mode to be 59 useful. Some public servers use it, and it saves a lot of memory by serving 60 tens of users from a single process. One crash affects all users, but these 61 are becoming quite rare. 43 62 44 63 … … 88 107 versions of make, we'd love to hear it, but it seems this just isn't 89 108 possible. 90 91 92 RUNNING ON SERVERS WITH MANY USERS93 ==================================94 95 BitlBee is not yet bug-free. Sometimes a bug causes the program to get into96 an infinite loop. Something you really don't want on a public server,97 especially when that machine is also used for other (mission-critical) things.98 For now we can't do much about it. We haven't seen that happen for a long99 time already on our own machines, but some people still manage to get100 themselves in nasty situations we haven't seen before.101 102 For now the best we can offer against this problem is bitlbeed, which allows103 you to setrlimit() the child processes to use no more than a specified104 number of CPU seconds. Not the best solution (not really a solution anyway),105 but certainly trashing one busy daemon process is better than trashing your106 whole machine.107 108 We don't believe adding a limit for bitlbee to /etc/security/limits.conf will109 work, because that file is only read by PAM (ie just for real login users,110 not daemons).111 112 See utils/bitlbeed.c for more information about the program.113 114 Just a little note: Now that we reach version 1.0, this shouldn't be that115 much of an issue anymore. However, on a public server, especially if you116 also use it for other things, it can't hurt to protect yourself against117 possible problems.118 109 119 110 -
doc/bitlbee.8
reb0714d r9b55485 44 44 45 45 \fBbitlbee\fP should be called by 46 .BR inetd (8). 47 (Or \fBbitlbeed\fP, 48 if you can't run and/or configure \fBinetd\fP.) There is an experimental 49 daemon mode too, in which BitlBee will serve all clients in one process 50 (and does not require inetd), but this mode is still experimental. 51 There are still some bugs left in BitlBee, and if they cause a crash, 52 that would terminate the BitlBee connection for all clients. 46 .BR inetd (8), 47 or you can run it as a stand-alone daemon. 53 48 .PP 54 49 .SH OPTIONS … … 62 57 Run in daemon mode. In this mode, BitlBee forks to the background and 63 58 waits for new connections. All clients will be served from one process. 64 This is still experimental. See the note above for more information.65 59 .IP "-F" 66 60 Run in ForkDaemon mode. This is similar to ordinary daemon mode, but every 67 client gets its own process. Easier to set up than inetd mode, butwithout61 client gets its own process. Easier to set up than inetd mode, and without 68 62 the possible stability issues. 69 63 .IP "-i \fIaddress\fP" -
doc/user-guide/Support.xml
reb0714d r9b55485 4 4 5 5 <sect1> 6 <title> BitlBee is beta software</title>6 <title>Disclaimer</title> 7 7 8 8 <para> 9 Although BitlBee has quite some functionality it is still beta. That means it 10 can crash at any time, corrupt your data or whatever. Don't use it in 11 any production environment and don't rely on it. 9 BitlBee doesn't come with a warranty and is still (and will probably always 10 be) under development. That means it can crash at any time, corrupt your 11 data or whatever. Don't use it in any production environment and don't rely 12 on it, or at least don't blame us if things blow up. :-) 12 13 </para> 13 14 -
doc/user-guide/commands.xml
reb0714d r9b55485 163 163 164 164 <para> 165 If you want, you can also tell BitlBee what nick to give the new contact. Of course you can also use the <emphasis>rename</emphasis> command for that, but sometimes this might be more convenient. 166 </para> 167 168 <para> 169 Adding -tmp adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. 165 If you want, you can also tell BitlBee what nick to give the new contact. The -tmp option adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. This normally won't show you any presence notifications. 170 166 </para> 171 167 </description> … … 532 528 533 529 <bitlbee-setting name="charset" type="string" scope="global"> 534 <default> iso8859-1</default>530 <default>utf-8</default> 535 531 <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values> 536 532 537 533 <description> 538 534 <para> 539 Th e charset setting enables you to use different character sets in BitlBee. These get converted to UTF-8 before sending and from UTF-8 when receiving.540 </para> 541 542 <para> 543 If you don't know what's the best value for this, at least iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://czyborra.com/charsets/iso8859.html535 This setting tells BitlBee what your IRC client sends and expects. It should be equal to the charset setting of your IRC client if you want to be able to send and receive non-ASCII text properly. 536 </para> 537 538 <para> 539 Most systems use UTF-8 these days. On older systems, an iso8859 charset may work better. For example, iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://www.unicodecharacter.com/charsets/iso8859.html 544 540 </para> 545 541 </description> … … 804 800 </bitlbee-setting> 805 801 802 <bitlbee-setting name="root_nick" type="string" scope="global"> 803 <default>root</default> 804 805 <description> 806 <para> 807 Normally the "bot" that takes all your BitlBee commands is called "root". If you don't like this name, you can rename it to anything else using the <emphasis>rename</emphasis> command, or by changing this setting. 808 </para> 809 </description> 810 </bitlbee-setting> 811 806 812 <bitlbee-setting name="save_on_quit" type="boolean" scope="global"> 807 813 <default>true</default> … … 888 894 <description> 889 895 <para> 890 Sends you a /notice when a user starts typing a message (if the protocol supports it, MSN for example). This is a bug, not a feature. (But please don't report it.. ;-) You don't want to use it. Really. In fact the typing-notification is just one of the least useful 'innovations' ever. It's just there because some guy will probably ask me about it anyway. ;-)896 Sends you a /notice when a user starts typing a message (if supported by the IM protocol and the user's client). To use this, you most likely want to use a script in your IRC client to show this information in a more sensible way. 891 897 </para> 892 898 </description> … … 1057 1063 <short-description>Change friendly name, nick</short-description> 1058 1064 <syntax>nick <connection> [<new nick>]</syntax> 1059 <syntax>nick</syntax> 1060 1061 <description> 1062 <para> 1063 This command allows to set the friendly name of an im account. If no new name is specified the command will report the current name. When the name contains spaces, don't forget to quote the whole nick in double quotes. Currently this command is only supported by the MSN protocol. 1064 </para> 1065 1066 <para> 1067 It is recommended to use the per-account <emphasis>display_name</emphasis> setting to read and change this information. The <emphasis>nick</emphasis> command is deprecated. 1065 <syntax>nick <connection></syntax> 1066 1067 <description> 1068 <para> 1069 Deprecated: Use the per-account <emphasis>display_name</emphasis> setting to read and change this information. 1068 1070 </para> 1069 1071 </description> 1070 1072 1071 1073 <ircexample> 1072 <ircline nick="wouter"> nick 1 "Wouter Paesen"</ircline>1073 <ircline nick="root"> Setting your name on connection 1 to `Wouter Paesen'</ircline>1074 <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline> 1075 <ircline nick="root">display_name = `The majestik møøse'</ircline> 1074 1076 </ircexample> 1075 1077 -
doc/user-guide/misc.xml
reb0714d r9b55485 47 47 </variablelist> 48 48 49 <para>50 This list was extracted from <ulink url="http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=">http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=</ulink>.51 </para>52 53 49 </sect1> 54 50 … … 56 52 <title>Groupchats</title> 57 53 <para> 58 Since version 0.8x, BitlBee supports groupchats on the MSN and Yahoo!networks. This text will try to explain you how they work.54 BitlBee now supports groupchats on all IM networks. This text will try to explain you how they work. 59 55 </para> 60 56 … … 73 69 74 70 <para> 75 If you want to start a groupchat with the person <emphasis> jim_msn</emphasis> in it, just join the channel <emphasis>#jim_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and jim_msn in it.71 If you want to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just join the channel <emphasis>#lisa_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and lisa_msn in it. 76 72 </para> 77 73 … … 82 78 <para> 83 79 Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>join_chat</emphasis> command to join them. See <emphasis>help join_chat</emphasis> for more information. 84 </para>85 86 <para>87 This is all you'll probably need to know. If you have any problems, please read <emphasis>help groupchats3</emphasis>.88 </para>89 90 </sect1>91 92 <sect1 id="groupchats3">93 <title>Groupchat channel names</title>94 95 <para>96 Obviously the (numbered) channel names don't make a lot of sense. Problem is that groupchats usually don't have names at all in the IM-world, while IRC insists on a name. So BitlBee just generates something random, just don't pay attention to it. :-)97 </para>98 99 <para>100 Please also note that BitlBee doesn't support groupchats for all protocols yet. BitlBee will tell you so. Support for other protocols will hopefully come later.101 80 </para> 102 81 … … 121 100 <member>On the phone, Phone, On phone</member> 122 101 <member>Out to lunch, Lunch, Food</member> 102 <member>Invisible, Hidden</member> 123 103 </simplelist> 124 104 … … 128 108 129 109 <para> 130 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Protocols like Yahoo! and Jabber will also show this complete away messageto your buddies.110 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Most IM-protocols can also show this additional information to your buddies. 131 111 </para> 132 112 -
doc/user-guide/quickstart.xml
reb0714d r9b55485 61 61 62 62 <para> 63 For most protocols (currently MSN, Jabber, Yahoo and AOL) BitlBee can download the contact list automatically from the IM server and all the on-line users should appear in the control channel when you log in.63 Now BitlBee logs in and downloads the contact list from the IM server. In a few seconds, all your on-line buddies should show up in the control channel. 64 64 </para> 65 65 66 66 <para> 67 BitlBee will convert names into irc-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo.67 BitlBee will convert names into IRC-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo. 68 68 </para> 69 69 … … 127 127 <ircexample> 128 128 <ircline nick="you">tux: hey, how's the weather down there?</ircline> 129 <ircline nick="tux"> 129 <ircline nick="tux">you: a bit chilly!</ircline> 130 130 </ircexample> 131 131 132 132 <para> 133 If you'd rather chat with them in a separate window use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like you would for a private message in IRC. If you want to have messages automatically come up in private messages rather than in the &bitlbee channel, use the <emphasis>set private</emphasis> command: <emphasis>set private true</emphasis> (<emphasis>set private false</emphasis> to change back). 133 Note that, although all contacts are in the &bitlbee channel, only tux will actually receive this message. The &bitlbee channel shouldn't be confused with a real IRC channel. 134 </para> 135 136 <para> 137 If you prefer chatting in a separate window, use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like on real IRC. BitlBee will remember how you talk to someone and show his/her responses the same way. If you want to change the default behaviour (for people you haven't talked to yet), see <emphasis>help set private</emphasis>. 134 138 </para> 135 139 -
ipc.c
reb0714d r9b55485 33 33 34 34 GSList *child_list = NULL; 35 static char *statefile = NULL;36 35 37 36 static void ipc_master_cmd_client( irc_t *data, char **cmd ) … … 63 62 } 64 63 64 static void ipc_master_cmd_deaf( irc_t *data, char **cmd ) 65 { 66 if( global.conf->runmode == RUNMODE_DAEMON ) 67 { 68 b_event_remove( global.listen_watch_source_id ); 69 close( global.listen_socket ); 70 71 global.listen_socket = global.listen_watch_source_id = -1; 72 73 ipc_to_children_str( "OPERMSG :Closed listening socket, waiting " 74 "for all users to disconnect." ); 75 } 76 else 77 { 78 ipc_to_children_str( "OPERMSG :The DEAF command only works in " 79 "normal daemon mode. Try DIE instead." ); 80 } 81 } 82 65 83 void ipc_master_cmd_rehash( irc_t *data, char **cmd ) 66 84 { … … 98 116 { "hello", 0, ipc_master_cmd_client, 0 }, 99 117 { "die", 0, ipc_master_cmd_die, 0 }, 118 { "deaf", 0, ipc_master_cmd_deaf, 0 }, 100 119 { "wallops", 1, NULL, IPC_CMD_TO_CHILDREN }, 101 120 { "wall", 1, NULL, IPC_CMD_TO_CHILDREN }, … … 209 228 } 210 229 230 /* Return just one line. Returns NULL if something broke, an empty string 231 on temporary "errors" (EAGAIN and friends). */ 211 232 static char *ipc_readline( int fd ) 212 233 { 213 char *buf, *eol;234 char buf[513], *eol; 214 235 int size; 215 216 buf = g_new0( char, 513 );217 236 218 237 /* Because this is internal communication, it should be pretty safe … … 221 240 sockets and limites message length, messages should always be 222 241 complete. Saves us quite a lot of code and buffering. */ 223 size = recv( fd, buf, 512, MSG_PEEK );242 size = recv( fd, buf, sizeof( buf ) - 1, MSG_PEEK ); 224 243 if( size == 0 || ( size < 0 && !sockerr_again() ) ) 225 244 return NULL; … … 229 248 buf[size] = 0; 230 249 231 eol = strstr( buf, "\r\n" ); 232 if( eol == NULL ) 250 if( ( eol = strstr( buf, "\r\n" ) ) == NULL ) 233 251 return NULL; 234 252 else 235 253 size = eol - buf + 2; 236 237 g_free( buf );238 buf = g_new0( char, size + 1 );239 254 240 255 if( recv( fd, buf, size, 0 ) != size ) 241 256 return NULL; 242 257 else 243 buf[size-2] = 0; 244 245 return buf; 258 return g_strndup( buf, size - 2 ); 246 259 } 247 260 … … 254 267 cmd = irc_parse_line( buf ); 255 268 if( cmd ) 269 { 256 270 ipc_command_exec( data, cmd, ipc_master_commands ); 257 } 258 else 271 g_free( cmd ); 272 } 273 g_free( buf ); 274 } 275 else 276 { 277 ipc_master_free_fd( source ); 278 } 279 280 return TRUE; 281 } 282 283 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond ) 284 { 285 char *buf, **cmd; 286 287 if( ( buf = ipc_readline( source ) ) ) 288 { 289 cmd = irc_parse_line( buf ); 290 if( cmd ) 291 { 292 ipc_command_exec( data, cmd, ipc_child_commands ); 293 g_free( cmd ); 294 } 295 g_free( buf ); 296 } 297 else 298 { 299 ipc_child_disable(); 300 } 301 302 return TRUE; 303 } 304 305 void ipc_to_master( char **cmd ) 306 { 307 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 308 { 309 char *s = irc_build_line( cmd ); 310 ipc_to_master_str( "%s", s ); 311 g_free( s ); 312 } 313 else if( global.conf->runmode == RUNMODE_DAEMON ) 314 { 315 ipc_command_exec( NULL, cmd, ipc_master_commands ); 316 } 317 } 318 319 void ipc_to_master_str( char *format, ... ) 320 { 321 char *msg_buf; 322 va_list params; 323 324 va_start( params, format ); 325 msg_buf = g_strdup_vprintf( format, params ); 326 va_end( params ); 327 328 if( strlen( msg_buf ) > 512 ) 329 { 330 /* Don't send it, it's too long... */ 331 } 332 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 333 { 334 if( global.listen_socket >= 0 ) 335 if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 ) 336 ipc_child_disable(); 337 } 338 else if( global.conf->runmode == RUNMODE_DAEMON ) 339 { 340 char **cmd, *s; 341 342 if( ( s = strchr( msg_buf, '\r' ) ) ) 343 *s = 0; 344 345 cmd = irc_parse_line( msg_buf ); 346 ipc_command_exec( NULL, cmd, ipc_master_commands ); 347 g_free( cmd ); 348 } 349 350 g_free( msg_buf ); 351 } 352 353 void ipc_to_children( char **cmd ) 354 { 355 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 356 { 357 char *msg_buf = irc_build_line( cmd ); 358 ipc_to_children_str( "%s", msg_buf ); 359 g_free( msg_buf ); 360 } 361 else if( global.conf->runmode == RUNMODE_DAEMON ) 259 362 { 260 363 GSList *l; 261 struct bitlbee_child *c; 262 263 for( l = child_list; l; l = l->next ) 364 365 for( l = irc_connection_list; l; l = l->next ) 366 ipc_command_exec( l->data, cmd, ipc_child_commands ); 367 } 368 } 369 370 void ipc_to_children_str( char *format, ... ) 371 { 372 char *msg_buf; 373 va_list params; 374 375 va_start( params, format ); 376 msg_buf = g_strdup_vprintf( format, params ); 377 va_end( params ); 378 379 if( strlen( msg_buf ) > 512 ) 380 { 381 /* Don't send it, it's too long... */ 382 } 383 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 384 { 385 int msg_len = strlen( msg_buf ); 386 GSList *l, *next; 387 388 for( l = child_list; l; l = next ) 264 389 { 265 c = l->data; 266 if( c->ipc_fd == source ) 390 struct bitlbee_child *c = l->data; 391 392 next = l->next; 393 if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 ) 267 394 { 268 395 ipc_master_free_one( c ); 269 396 child_list = g_slist_remove( child_list, c ); 270 break;271 397 } 272 }273 }274 275 return TRUE;276 }277 278 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )279 {280 char *buf, **cmd;281 282 if( ( buf = ipc_readline( source ) ) )283 {284 cmd = irc_parse_line( buf );285 if( cmd )286 ipc_command_exec( data, cmd, ipc_child_commands );287 }288 else289 {290 b_event_remove( global.listen_watch_source_id );291 close( global.listen_socket );292 293 global.listen_socket = -1;294 }295 296 return TRUE;297 }298 299 void ipc_to_master( char **cmd )300 {301 if( global.conf->runmode == RUNMODE_FORKDAEMON )302 {303 char *s = irc_build_line( cmd );304 ipc_to_master_str( "%s", s );305 g_free( s );306 }307 else if( global.conf->runmode == RUNMODE_DAEMON )308 {309 ipc_command_exec( NULL, cmd, ipc_master_commands );310 }311 }312 313 void ipc_to_master_str( char *format, ... )314 {315 char *msg_buf;316 va_list params;317 318 va_start( params, format );319 msg_buf = g_strdup_vprintf( format, params );320 va_end( params );321 322 if( strlen( msg_buf ) > 512 )323 {324 /* Don't send it, it's too long... */325 }326 else if( global.conf->runmode == RUNMODE_FORKDAEMON )327 {328 write( global.listen_socket, msg_buf, strlen( msg_buf ) );329 }330 else if( global.conf->runmode == RUNMODE_DAEMON )331 {332 char **cmd, *s;333 334 if( ( s = strchr( msg_buf, '\r' ) ) )335 *s = 0;336 337 cmd = irc_parse_line( msg_buf );338 ipc_command_exec( NULL, cmd, ipc_master_commands );339 g_free( cmd );340 }341 342 g_free( msg_buf );343 }344 345 void ipc_to_children( char **cmd )346 {347 if( global.conf->runmode == RUNMODE_FORKDAEMON )348 {349 char *msg_buf = irc_build_line( cmd );350 ipc_to_children_str( "%s", msg_buf );351 g_free( msg_buf );352 }353 else if( global.conf->runmode == RUNMODE_DAEMON )354 {355 GSList *l;356 357 for( l = irc_connection_list; l; l = l->next )358 ipc_command_exec( l->data, cmd, ipc_child_commands );359 }360 }361 362 void ipc_to_children_str( char *format, ... )363 {364 char *msg_buf;365 va_list params;366 367 va_start( params, format );368 msg_buf = g_strdup_vprintf( format, params );369 va_end( params );370 371 if( strlen( msg_buf ) > 512 )372 {373 /* Don't send it, it's too long... */374 }375 else if( global.conf->runmode == RUNMODE_FORKDAEMON )376 {377 int msg_len = strlen( msg_buf );378 GSList *l;379 380 for( l = child_list; l; l = l->next )381 {382 struct bitlbee_child *c = l->data;383 write( c->ipc_fd, msg_buf, msg_len );384 398 } 385 399 } … … 410 424 } 411 425 426 void ipc_master_free_fd( int fd ) 427 { 428 GSList *l; 429 struct bitlbee_child *c; 430 431 for( l = child_list; l; l = l->next ) 432 { 433 c = l->data; 434 if( c->ipc_fd == fd ) 435 { 436 ipc_master_free_one( c ); 437 child_list = g_slist_remove( child_list, c ); 438 break; 439 } 440 } 441 } 442 412 443 void ipc_master_free_all() 413 444 { … … 421 452 } 422 453 454 void ipc_child_disable() 455 { 456 b_event_remove( global.listen_watch_source_id ); 457 close( global.listen_socket ); 458 459 global.listen_socket = -1; 460 } 461 462 #ifndef _WIN32 423 463 char *ipc_master_save_state() 424 464 { … … 461 501 } 462 502 463 void ipc_master_set_statefile( char *fn )464 {465 statefile = g_strdup( fn );466 }467 468 503 469 504 static gboolean new_ipc_client( gpointer data, gint serversock, b_input_condition cond ) … … 486 521 } 487 522 488 #ifndef _WIN32489 523 int ipc_master_listen_socket() 490 524 { … … 523 557 } 524 558 #else 559 int ipc_master_listen_socket() 560 { 525 561 /* FIXME: Open named pipe \\.\BITLBEE */ 562 return 0; 563 } 526 564 #endif 527 565 528 int ipc_master_load_state( )566 int ipc_master_load_state( char *statefile ) 529 567 { 530 568 struct bitlbee_child *child; … … 534 572 if( statefile == NULL ) 535 573 return 0; 574 536 575 fp = fopen( statefile, "r" ); 537 576 unlink( statefile ); /* Why do it later? :-) */ -
ipc.h
reb0714d r9b55485 44 44 45 45 void ipc_master_free_one( struct bitlbee_child *child ); 46 void ipc_master_free_fd( int fd ); 46 47 void ipc_master_free_all(); 48 49 void ipc_child_disable(); 47 50 48 51 void ipc_to_master( char **cmd ); … … 55 58 56 59 char *ipc_master_save_state(); 57 void ipc_master_set_statefile( char *fn ); 58 int ipc_master_load_state(); 60 int ipc_master_load_state( char *statefile ); 59 61 int ipc_master_listen_socket(); 60 62 -
irc.c
reb0714d r9b55485 26 26 #define BITLBEE_CORE 27 27 #include "bitlbee.h" 28 #include "sock.h" 28 29 #include "crypting.h" 29 30 #include "ipc.h" … … 45 46 } 46 47 48 static char *set_eval_charset( set_t *set, char *value ) 49 { 50 irc_t *irc = set->data; 51 GIConv ic, oc; 52 53 if( g_strcasecmp( value, "none" ) == 0 ) 54 value = g_strdup( "utf-8" ); 55 56 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 57 { 58 return NULL; 59 } 60 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 61 { 62 g_iconv_close( ic ); 63 return NULL; 64 } 65 66 if( irc->iconv != (GIConv) -1 ) 67 g_iconv_close( irc->iconv ); 68 if( irc->oconv != (GIConv) -1 ) 69 g_iconv_close( irc->oconv ); 70 71 irc->iconv = ic; 72 irc->oconv = oc; 73 74 return value; 75 } 76 47 77 irc_t *irc_new( int fd ) 48 78 { … … 67 97 irc->mynick = g_strdup( ROOT_NICK ); 68 98 irc->channel = g_strdup( ROOT_CHAN ); 99 100 irc->iconv = (GIConv) -1; 101 irc->oconv = (GIConv) -1; 69 102 70 103 if( global.conf->hostname ) … … 126 159 set_add( &irc->set, "private", "true", set_eval_bool, irc ); 127 160 set_add( &irc->set, "query_order", "lifo", NULL, irc ); 161 set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 128 162 set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 129 163 set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); … … 137 171 irc->otr = otr_new(); 138 172 173 /* Evaluator sets the iconv/oconv structures. */ 174 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 175 139 176 return( irc ); 140 177 } … … 174 211 if( irc->sendbuffer && !immed ) 175 212 { 176 /* We won't read from this socket anymore. Instead, we'll connect a timer 177 to it that should shut down the connection in a second, just in case 178 bitlbee_.._write doesn't do it first. */ 213 /* Set up a timeout event that should shut down the connection 214 in a second, just in case ..._write doesn't do it first. */ 179 215 180 216 b_event_remove( irc->r_watch_source_id ); 181 irc->r_watch_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc ); 217 irc->r_watch_source_id = 0; 218 219 b_event_remove( irc->ping_source_id ); 220 irc->ping_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc ); 182 221 } 183 222 else … … 195 234 196 235 /* Because we have no garbage collection, this is quite annoying */ 197 void irc_free(irc_t * irc) 198 { 199 account_t *account; 236 void irc_free( irc_t * irc ) 237 { 200 238 user_t *user, *usertmp; 201 239 … … 206 244 irc_usermsg( irc, "Error while saving settings!" ); 207 245 208 closesocket( irc->fd );209 210 if( irc->ping_source_id > 0 )211 b_event_remove( irc->ping_source_id );212 b_event_remove( irc->r_watch_source_id );213 if( irc->w_watch_source_id > 0 )214 b_event_remove( irc->w_watch_source_id );215 216 246 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 217 247 218 for (account = irc->accounts; account; account = account->next) { 219 if (account->ic) { 220 imc_logout(account->ic, TRUE); 221 } else if (account->reconnect) { 222 cancel_auto_reconnect(account); 223 } 224 } 225 226 g_free(irc->sendbuffer); 227 g_free(irc->readbuffer); 228 229 g_free(irc->nick); 230 g_free(irc->user); 231 g_free(irc->host); 232 g_free(irc->realname); 233 g_free(irc->password); 234 235 g_free(irc->myhost); 236 g_free(irc->mynick); 237 238 g_free(irc->channel); 239 240 while (irc->queries != NULL) 241 query_del(irc, irc->queries); 242 243 while (irc->accounts) 244 if (irc->accounts->ic == NULL) 245 account_del(irc, irc->accounts); 248 while( irc->accounts ) 249 { 250 if( irc->accounts->ic ) 251 imc_logout( irc->accounts->ic, FALSE ); 252 else if( irc->accounts->reconnect ) 253 cancel_auto_reconnect( irc->accounts ); 254 255 if( irc->accounts->ic == NULL ) 256 account_del( irc, irc->accounts ); 246 257 else 247 258 /* Nasty hack, but account_del() doesn't work in this 248 259 case and we don't want infinite loops, do we? ;-) */ 249 260 irc->accounts = irc->accounts->next; 250 251 while (irc->set) 252 set_del(&irc->set, irc->set->key); 253 254 if (irc->users != NULL) { 261 } 262 263 while( irc->queries != NULL ) 264 query_del( irc, irc->queries ); 265 266 while( irc->set ) 267 set_del( &irc->set, irc->set->key ); 268 269 if (irc->users != NULL) 270 { 255 271 user = irc->users; 256 while (user != NULL) { 257 g_free(user->nick); 258 g_free(user->away); 259 g_free(user->handle); 260 if(user->user!=user->nick) g_free(user->user); 261 if(user->host!=user->nick) g_free(user->host); 262 if(user->realname!=user->nick) g_free(user->realname); 263 b_event_remove(user->sendbuf_timer); 272 while( user != NULL ) 273 { 274 g_free( user->nick ); 275 g_free( user->away ); 276 g_free( user->handle ); 277 if( user->user != user->nick ) g_free( user->user ); 278 if( user->host != user->nick ) g_free( user->host ); 279 if( user->realname != user->nick ) g_free( user->realname ); 280 b_event_remove( user->sendbuf_timer ); 264 281 265 282 usertmp = user; 266 283 user = user->next; 267 g_free(usertmp); 268 } 269 } 270 271 g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL); 272 g_hash_table_destroy(irc->userhash); 273 274 g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); 275 g_hash_table_destroy(irc->watches); 284 g_free( usertmp ); 285 } 286 } 287 288 if( irc->ping_source_id > 0 ) 289 b_event_remove( irc->ping_source_id ); 290 if( irc->r_watch_source_id > 0 ) 291 b_event_remove( irc->r_watch_source_id ); 292 if( irc->w_watch_source_id > 0 ) 293 b_event_remove( irc->w_watch_source_id ); 294 295 closesocket( irc->fd ); 296 irc->fd = -1; 297 298 g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); 299 g_hash_table_destroy( irc->userhash ); 300 301 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); 302 g_hash_table_destroy( irc->watches ); 303 304 if( irc->iconv != (GIConv) -1 ) 305 g_iconv_close( irc->iconv ); 306 if( irc->oconv != (GIConv) -1 ) 307 g_iconv_close( irc->oconv ); 308 309 g_free( irc->sendbuffer ); 310 g_free( irc->readbuffer ); 311 312 g_free( irc->nick ); 313 g_free( irc->user ); 314 g_free( irc->host ); 315 g_free( irc->realname ); 316 g_free( irc->password ); 317 318 g_free( irc->myhost ); 319 g_free( irc->mynick ); 320 321 g_free( irc->channel ); 322 323 g_free( irc->last_target ); 276 324 277 325 otr_free(irc->otr); 278 326 279 g_free(irc); 280 281 if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) 327 g_free( irc ); 328 329 if( global.conf->runmode == RUNMODE_INETD || 330 global.conf->runmode == RUNMODE_FORKDAEMON || 331 ( global.conf->runmode == RUNMODE_DAEMON && 332 global.listen_socket == -1 && 333 irc_connection_list == NULL ) ) 282 334 b_main_quit(); 283 335 } … … 298 350 void irc_process( irc_t *irc ) 299 351 { 300 char **lines, *temp, **cmd , *cs;352 char **lines, *temp, **cmd; 301 353 int i; 302 354 … … 307 359 for( i = 0; *lines[i] != '\0'; i ++ ) 308 360 { 309 char conv[IRC_MAX_LINE+1];361 char *conv = NULL; 310 362 311 /* [WvG] Because irc_tokenize splits at every newline, the lines[] list 312 should end with an empty string. This is why this actually works. 313 Took me a while to figure out, Maurits. :-P */ 363 /* [WvG] If the last line isn't empty, it's an incomplete line and we 364 should wait for the rest to come in before processing it. */ 314 365 if( lines[i+1] == NULL ) 315 366 { … … 321 372 } 322 373 323 if( ( cs = set_getstr( &irc->set, "charset" ) ) ) 324 { 325 conv[IRC_MAX_LINE] = 0; 326 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) 374 if( irc->iconv != (GIConv) -1 ) 375 { 376 gsize bytes_read, bytes_written; 377 378 conv = g_convert_with_iconv( lines[i], -1, irc->iconv, 379 &bytes_read, &bytes_written, NULL ); 380 381 if( conv == NULL || bytes_read != strlen( lines[i] ) ) 327 382 { 328 383 /* GLib can do strange things if things are not in the expected charset, … … 336 391 "expect by changing the charset setting. See " 337 392 "`help set charset' for more information. Your " 338 "message was ignored.", cs ); 339 *conv = 0; 393 "message was ignored.", 394 set_getstr( &irc->set, "charset" ) ); 395 396 g_free( conv ); 397 conv = NULL; 340 398 } 341 399 else 342 400 { 343 401 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, 344 "Warning: invalid (non-UTF8)characters received at login time." );402 "Warning: invalid characters received at login time." ); 345 403 346 strncpy( conv, lines[i], IRC_MAX_LINE);404 conv = g_strdup( lines[i] ); 347 405 for( temp = conv; *temp; temp ++ ) 348 406 if( *temp & 0x80 ) … … 353 411 } 354 412 355 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 356 continue; 357 irc_exec( irc, cmd ); 413 if( lines[i] ) 414 { 415 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 416 continue; 417 irc_exec( irc, cmd ); 418 g_free( cmd ); 419 } 358 420 359 g_free( c md);421 g_free( conv ); 360 422 361 423 /* Shouldn't really happen, but just in case... */ … … 381 443 char **irc_tokenize( char *buffer ) 382 444 { 383 int i, j ;445 int i, j, n = 3; 384 446 char **lines; 385 447 386 /* Count the number of elements we're gonna need. */ 387 for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) 388 { 389 if( buffer[i] == '\n' ) 390 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 391 j ++; 392 } 393 394 /* Allocate j+1 elements. */ 395 lines = g_new( char *, j + 1 ); 448 /* Allocate n+1 elements. */ 449 lines = g_new( char *, n + 1 ); 450 451 lines[0] = buffer; 452 453 /* Split the buffer in several strings, and accept any kind of line endings, 454 * knowing that ERC on Windows may send something interesting like \r\r\n, 455 * and surely there must be clients that think just \n is enough... */ 456 for( i = 0, j = 0; buffer[i] != '\0'; i ++ ) 457 { 458 if( buffer[i] == '\r' || buffer[i] == '\n' ) 459 { 460 while( buffer[i] == '\r' || buffer[i] == '\n' ) 461 buffer[i++] = '\0'; 462 463 lines[++j] = buffer + i; 464 465 if( j >= n ) 466 { 467 n *= 2; 468 lines = g_renew( char *, lines, n + 1 ); 469 } 470 471 if( buffer[i] == '\0' ) 472 break; 473 } 474 } 396 475 397 476 /* NULL terminate our list. */ 398 lines[j] = NULL; 399 400 lines[0] = buffer; 401 402 /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. 403 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. 404 */ 405 for( i = 0, j = 0; buffer[i] != '\0'; i ++) 406 { 407 if( buffer[i] == '\n' ) 408 { 409 buffer[i] = '\0'; 410 411 if( i > 0 && buffer[i-1] == '\r' ) 412 buffer[i-1] = '\0'; 413 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 414 lines[++j] = buffer + i + 1; 415 } 416 } 417 418 return( lines ); 477 lines[++j] = NULL; 478 479 return lines; 419 480 } 420 481 … … 550 611 551 612 return; 552 553 613 } 554 614 … … 556 616 { 557 617 int size; 558 char line[IRC_MAX_LINE+1] , *cs;618 char line[IRC_MAX_LINE+1]; 559 619 560 620 /* Don't try to write anything new anymore when shutting down. */ … … 562 622 return; 563 623 564 line[IRC_MAX_LINE] = 0;624 memset( line, 0, sizeof( line ) ); 565 625 g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); 566 567 626 strip_newlines( line ); 568 if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) 569 { 570 char conv[IRC_MAX_LINE+1]; 571 572 conv[IRC_MAX_LINE] = 0; 573 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 ) 574 strcpy( line, conv ); 575 } 576 strcat( line, "\r\n" ); 627 628 if( irc->oconv != (GIConv) -1 ) 629 { 630 gsize bytes_read, bytes_written; 631 char *conv; 632 633 conv = g_convert_with_iconv( line, -1, irc->oconv, 634 &bytes_read, &bytes_written, NULL ); 635 636 if( bytes_read == strlen( line ) ) 637 strncpy( line, conv, IRC_MAX_LINE - 2 ); 638 639 g_free( conv ); 640 } 641 g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 ); 577 642 578 643 if( irc->sendbuffer != NULL ) … … 753 818 irc->umode[0] = '\0'; 754 819 irc_umode_set( irc, "+" UMODE, 1 ); 755 756 u = user_add( irc, irc->mynick ); 820 u = user_add( irc, irc->mynick ); 757 821 u->host = g_strdup( irc->myhost ); 758 822 u->realname = g_strdup( ROOT_FN ); … … 782 846 783 847 irc->status |= USTATUS_LOGGED_IN; 848 849 /* This is for bug #209 (use PASS to identify to NickServ). */ 850 if( irc->password != NULL ) 851 { 852 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 853 854 irc_setpass( irc, NULL ); 855 root_command( irc, send_cmd ); 856 g_free( send_cmd[1] ); 857 } 784 858 } 785 859 … … 791 865 if( !f ) 792 866 { 793 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there.\n\nOTR users please note: Private key files are owned by the user BitlBee is running as." ); 867 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" 868 "If you've never used BitlBee before, please do read the help " 869 "information using the \x02help\x02 command. Lots of FAQs are " 870 "answered there.\n" 871 "OTR users please note: Private key files are owned by the user " 872 "BitlBee is running as.\n" 873 "If you already have an account on this server, just use the " 874 "\x02identify\x02 command to identify yourself." ); 794 875 } 795 876 else -
irc.h
reb0714d r9b55485 63 63 char *sendbuffer; 64 64 char *readbuffer; 65 GIConv iconv, oconv; 65 66 66 67 int sentbytes; … … 71 72 char *host; 72 73 char *realname; 73 char *password; 74 char *password; /* HACK: Used to save the user's password, but before 75 logging in, this may contain a password we should 76 send to identify after USER/NICK are received. */ 74 77 75 78 char umode[8]; -
irc_commands.c
reb0714d r9b55485 30 30 static void irc_cmd_pass( irc_t *irc, char **cmd ) 31 31 { 32 if( global.conf->auth_pass && strcmp( cmd[1], global.conf->auth_pass ) == 0 ) 32 if( irc->status & USTATUS_LOGGED_IN ) 33 { 34 char *send_cmd[] = { "identify", cmd[1], NULL }; 35 36 /* We're already logged in, this client seems to send the PASS 37 command last. (Possibly it won't send it at all if it turns 38 out we don't require it, which will break this feature.) 39 Try to identify using the given password. */ 40 return root_command( irc, send_cmd ); 41 } 42 /* Handling in pre-logged-in state, first see if this server is 43 password-protected: */ 44 else if( global.conf->auth_pass && 45 ( strncmp( global.conf->auth_pass, "md5:", 4 ) == 0 ? 46 md5_verify_password( cmd[1], global.conf->auth_pass + 4 ) == 0 : 47 strcmp( cmd[1], global.conf->auth_pass ) == 0 ) ) 33 48 { 34 49 irc->status |= USTATUS_AUTHORIZED; 35 50 irc_check_login( irc ); 36 51 } 37 else 52 else if( global.conf->auth_pass ) 38 53 { 39 54 irc_reply( irc, 464, ":Incorrect password" ); 55 } 56 else 57 { 58 /* Remember the password and try to identify after USER/NICK. */ 59 irc_setpass( irc, cmd[1] ); 60 irc_check_login( irc ); 40 61 } 41 62 } … … 88 109 static void irc_cmd_oper( irc_t *irc, char **cmd ) 89 110 { 90 if( global.conf->oper_pass && strcmp( cmd[2], global.conf->oper_pass ) == 0 ) 111 if( global.conf->oper_pass && 112 ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? 113 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : 114 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) 91 115 { 92 116 irc_umode_set( irc, "+o", 1 ); … … 254 278 if( cmd[1] != irc->last_target ) 255 279 { 256 if( irc->last_target ) 257 g_free( irc->last_target ); 280 g_free( irc->last_target ); 258 281 irc->last_target = g_strdup( cmd[1] ); 259 282 } … … 575 598 576 599 static const command_t irc_commands[] = { 577 { "pass", 1, irc_cmd_pass, IRC_CMD_PRE_LOGIN},600 { "pass", 1, irc_cmd_pass, 0 }, 578 601 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, 579 602 { "nick", 1, irc_cmd_nick, 0 }, … … 603 626 { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN }, 604 627 { "die", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 628 { "deaf", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 605 629 { "wallops", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 606 630 { "wall", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, -
lib/Makefile
reb0714d r9b55485 10 10 11 11 # [SH] Program variables 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 13 13 14 14 CFLAGS += -Wall -
lib/arc.c
reb0714d r9b55485 131 131 132 132 Both functions return the number of bytes in the result string. 133 134 Note that if you use the pad_to argument, you will need zero-termi- 135 nation to find back the original string length after decryption. So 136 it shouldn't be used if your string contains \0s by itself! 133 137 */ 134 138 135 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password )139 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to ) 136 140 { 137 141 struct arc_state *st; 138 142 unsigned char *key; 139 int key_len, i; 143 char *padded = NULL; 144 int key_len, i, padded_len; 140 145 141 146 key_len = strlen( password ) + ARC_IV_LEN; 142 147 if( clear_len <= 0 ) 143 148 clear_len = strlen( clear ); 149 150 /* Pad the string to the closest multiple of pad_to. This makes it 151 impossible to see the exact length of the password. */ 152 if( pad_to > 0 && ( clear_len % pad_to ) > 0 ) 153 { 154 padded_len = clear_len + pad_to - ( clear_len % pad_to ); 155 padded = g_malloc( padded_len ); 156 memcpy( padded, clear, clear_len ); 157 158 /* First a \0 and then random data, so we don't have to do 159 anything special when decrypting. */ 160 padded[clear_len] = 0; 161 random_bytes( (unsigned char*) padded + clear_len + 1, padded_len - clear_len - 1 ); 162 163 clear = padded; 164 clear_len = padded_len; 165 } 144 166 145 167 /* Prepare buffers and the key + IV */ … … 161 183 162 184 g_free( st ); 185 g_free( padded ); 163 186 164 187 return clear_len + ARC_IV_LEN; -
lib/arc.h
reb0714d r9b55485 31 31 }; 32 32 33 struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles ); 33 #ifndef G_GNUC_MALLOC 34 #define G_GNUC_MALLOC 35 #endif 36 37 G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles ); 34 38 unsigned char arc_getbyte( struct arc_state *st ); 35 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password );39 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to ); 36 40 int arc_decode( unsigned char *crypt, int crypt_len, char **clear, char *password ); -
lib/base64.c
reb0714d r9b55485 118 118 int i, outlen = 0; 119 119 120 for( i = 0; in[i] ; i += 4 )120 for( i = 0; in[i] && in[i+1] && in[i+2] && in[i+3]; i += 4 ) 121 121 { 122 122 int sx; -
lib/events_glib.c
reb0714d r9b55485 51 51 } GaimIOClosure; 52 52 53 static GMainLoop *loop ;53 static GMainLoop *loop = NULL; 54 54 55 55 void b_main_init() 56 56 { 57 loop = g_main_new( FALSE ); 57 if( loop == NULL ) 58 loop = g_main_new( FALSE ); 58 59 } 59 60 -
lib/misc.c
reb0714d r9b55485 33 33 #define BITLBEE_CORE 34 34 #include "nogaim.h" 35 #include "base64.h" 35 36 #include <stdio.h> 36 37 #include <stdlib.h> … … 59 60 strcpy(text, text2); 60 61 g_free(text2); 61 }62 63 char *normalize(const char *s)64 {65 static char buf[BUF_LEN];66 char *t, *u;67 int x = 0;68 69 g_return_val_if_fail((s != NULL), NULL);70 71 u = t = g_strdup(s);72 73 strcpy(t, s);74 g_strdown(t);75 76 while (*t && (x < BUF_LEN - 1)) {77 if (*t != ' ') {78 buf[x] = *t;79 x++;80 }81 t++;82 }83 buf[x] = '\0';84 g_free(u);85 return buf;86 62 } 87 63 … … 408 384 void random_bytes( unsigned char *buf, int count ) 409 385 { 386 #ifndef _WIN32 410 387 static int use_dev = -1; 411 388 … … 457 434 458 435 if( !use_dev ) 436 #endif 459 437 { 460 438 int i; … … 608 586 return sockerr_again(); 609 587 } 588 589 /* Returns values: -1 == Failure (base64-decoded to something unexpected) 590 0 == Okay 591 1 == Password doesn't match the hash. */ 592 int md5_verify_password( char *password, char *hash ) 593 { 594 md5_byte_t *pass_dec = NULL; 595 md5_byte_t pass_md5[16]; 596 md5_state_t md5_state; 597 int ret = -1, i; 598 599 if( base64_decode( hash, &pass_dec ) == 21 ) 600 { 601 md5_init( &md5_state ); 602 md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) ); 603 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 604 md5_finish( &md5_state, pass_md5 ); 605 606 for( i = 0; i < 16; i ++ ) 607 { 608 if( pass_dec[i] != pass_md5[i] ) 609 { 610 ret = 1; 611 break; 612 } 613 } 614 615 /* If we reached the end of the loop, it was a match! */ 616 if( i == 16 ) 617 ret = 0; 618 } 619 620 g_free( pass_dec ); 621 622 return ret; 623 } -
lib/misc.h
reb0714d r9b55485 41 41 G_MODULE_EXPORT char *add_cr( char *text ); 42 42 G_MODULE_EXPORT char *strip_newlines(char *source); 43 G_MODULE_EXPORT char *normalize( const char *s );44 43 45 44 G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec ); … … 67 66 G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl ); 68 67 68 G_MODULE_EXPORT int md5_verify_password( char *password, char *hash ); 69 69 70 #endif -
lib/proxy.c
reb0714d r9b55485 114 114 { 115 115 struct sockaddr_in *sin; 116 struct sockaddr_in me; 116 117 int fd = -1; 117 118 … … 127 128 128 129 sock_make_nonblocking(fd); 130 131 if( global.conf->iface_out ) 132 { 133 me.sin_family = AF_INET; 134 me.sin_port = 0; 135 me.sin_addr.s_addr = inet_addr( global.conf->iface_out ); 136 137 if( bind( fd, (struct sockaddr *) &me, sizeof( me ) ) != 0 ) 138 event_debug( "bind( %d, \"%s\" ) failure\n", fd, global.conf->iface_out ); 139 } 129 140 130 141 event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd); … … 530 541 struct PHB *phb; 531 542 532 if (!host || !port || (port == -1)|| !func || strlen(host) > 128) {543 if (!host || port <= 0 || !func || strlen(host) > 128) { 533 544 return -1; 534 545 } … … 538 549 phb->data = data; 539 550 540 if ( (proxytype == PROXY_NONE) || strlen(proxyhost) > 0 || !proxyport || (proxyport == -1))551 if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) 541 552 return proxy_connect_none(host, port, phb); 542 553 else if (proxytype == PROXY_HTTP) -
lib/ssl_bogus.c
reb0714d r9b55485 65 65 return GAIM_INPUT_READ; 66 66 } 67 68 int ssl_pending( void *conn ) 69 { 70 return 0; 71 } -
lib/ssl_client.h
reb0714d r9b55485 63 63 G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); 64 64 65 /* See ssl_openssl.c for an explanation. */ 66 G_MODULE_EXPORT int ssl_pending( void *conn ); 67 65 68 /* Abort the SSL connection and disconnect the socket. Do not use close() 66 69 directly, both the SSL library and the peer will be unhappy! */ -
lib/ssl_gnutls.c
reb0714d r9b55485 216 216 } 217 217 218 /* See ssl_openssl.c for an explanation. */ 219 int ssl_pending( void *conn ) 220 { 221 return 0; 222 } 223 218 224 void ssl_disconnect( void *conn_ ) 219 225 { -
lib/ssl_nss.c
reb0714d r9b55485 175 175 } 176 176 177 /* See ssl_openssl.c for an explanation. */ 178 int ssl_pending( void *conn ) 179 { 180 return 0; 181 } 182 177 183 void ssl_disconnect( void *conn_ ) 178 184 { -
lib/ssl_openssl.c
reb0714d r9b55485 68 68 69 69 conn->fd = proxy_connect( host, port, ssl_connected, conn ); 70 if( conn->fd < 0 ) 71 { 72 g_free( conn ); 73 return NULL; 74 } 75 70 76 conn->func = func; 71 77 conn->data = data; 72 78 conn->inpa = -1; 73 74 if( conn->fd < 0 )75 {76 g_free( conn );77 return NULL;78 }79 79 80 80 return conn; … … 236 236 } 237 237 238 /* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info: 239 http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209 240 http://www.openssl.org/docs/ssl/SSL_pending.html 241 242 Required because OpenSSL empties the TCP buffer completely but doesn't 243 necessarily give us all the unencrypted data. 244 245 Returns 0 if there's nothing left or if we don't have to care (GnuTLS), 246 1 if there's more data. */ 247 int ssl_pending( void *conn ) 248 { 249 return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ? 250 SSL_pending( ((struct scd*)conn)->ssl ) > 0 : 0; 251 } 252 238 253 void ssl_disconnect( void *conn_ ) 239 254 { -
lib/url.c
reb0714d r9b55485 26 26 #include "url.h" 27 27 28 /* Convert an URL to a url_t structure 28 /* Convert an URL to a url_t structure */ 29 29 int url_set( url_t *url, char *set_url ) 30 30 { 31 char s[MAX_STRING ];31 char s[MAX_STRING+1]; 32 32 char *i; 33 33 34 /* protocol:// */ 34 memset( url, 0, sizeof( url_t ) ); 35 memset( s, 0, sizeof( s ) ); 36 37 /* protocol:// */ 35 38 if( ( i = strstr( set_url, "://" ) ) == NULL ) 36 39 { … … 49 52 url->proto = PROTO_SOCKS5; 50 53 else 51 { 52 return( 0 ); 53 } 54 return 0; 55 54 56 strncpy( s, i + 3, MAX_STRING ); 55 57 } 56 58 57 /* Split 59 /* Split */ 58 60 if( ( i = strchr( s, '/' ) ) == NULL ) 59 61 { … … 67 69 strncpy( url->host, s, MAX_STRING ); 68 70 69 /* Check for username in host field 71 /* Check for username in host field */ 70 72 if( strrchr( url->host, '@' ) != NULL ) 71 73 { … … 76 78 *url->pass = 0; 77 79 } 78 /* If not: Fill in defaults 80 /* If not: Fill in defaults */ 79 81 else 80 82 { … … 82 84 } 83 85 84 /* Password? 86 /* Password? */ 85 87 if( ( i = strchr( url->user, ':' ) ) != NULL ) 86 88 { … … 88 90 strcpy( url->pass, i + 1 ); 89 91 } 90 /* Port number? 92 /* Port number? */ 91 93 if( ( i = strchr( url->host, ':' ) ) != NULL ) 92 94 { -
lib/url.h
reb0714d r9b55485 26 26 #include "bitlbee.h" 27 27 28 #define PROTO_HTTP 29 #define PROTO_HTTPS 30 #define PROTO_SOCKS4 31 #define PROTO_SOCKS5 32 #define PROTO_DEFAULT 28 #define PROTO_HTTP 2 29 #define PROTO_HTTPS 5 30 #define PROTO_SOCKS4 3 31 #define PROTO_SOCKS5 4 32 #define PROTO_DEFAULT PROTO_HTTP 33 33 34 34 typedef struct url … … 36 36 int proto; 37 37 int port; 38 char host[MAX_STRING ];39 char file[MAX_STRING ];40 char user[MAX_STRING ];41 char pass[MAX_STRING ];38 char host[MAX_STRING+1]; 39 char file[MAX_STRING+1]; 40 char user[MAX_STRING+1]; 41 char pass[MAX_STRING+1]; 42 42 } url_t; 43 43 -
nick.c
reb0714d r9b55485 47 47 48 48 store_handle = clean_handle( handle ); 49 store_nick[MAX_NICK_LENGTH] = 0; 49 50 strncpy( store_nick, nick, MAX_NICK_LENGTH ); 50 51 nick_strip( store_nick ); -
otr.c
reb0714d r9b55485 46 46 #include <unistd.h> 47 47 #include <assert.h> 48 #include <signal.h> 48 49 49 50 … … 102 103 }; 103 104 105 typedef struct { 106 void *fst; 107 void *snd; 108 } pair_t; 109 104 110 105 111 /** misc. helpers/subroutines: **/ … … 124 130 125 131 /* some yes/no handlers */ 126 void yes_keygen( gpointer w,void *data);127 void yes_forget_fingerprint( gpointer w,void *data);128 void yes_forget_context( gpointer w,void *data);129 void yes_forget_key( gpointer w,void *data);132 void yes_keygen(void *data); 133 void yes_forget_fingerprint(void *data); 134 void yes_forget_context(void *data); 135 void yes_forget_key(void *data); 130 136 131 137 /* helper to make sure accountname and protocol match the incoming "opdata" */ … … 841 847 } 842 848 843 void yes_forget_fingerprint(gpointer w, void *data) 844 { 845 irc_t *irc = (irc_t *)w; 846 Fingerprint *fp = (Fingerprint *)data; 849 void yes_forget_fingerprint(void *data) 850 { 851 pair_t *p = (pair_t *)data; 852 irc_t *irc = (irc_t *)p->fst; 853 Fingerprint *fp = (Fingerprint *)p->snd; 854 855 g_free(p); 847 856 848 857 if(fp == fp->context->active_fingerprint) { … … 854 863 } 855 864 856 void yes_forget_context(gpointer w, void *data) 857 { 858 irc_t *irc = (irc_t *)w; 859 ConnContext *ctx = (ConnContext *)data; 865 void yes_forget_context(void *data) 866 { 867 pair_t *p = (pair_t *)data; 868 irc_t *irc = (irc_t *)p->fst; 869 ConnContext *ctx = (ConnContext *)p->snd; 870 871 g_free(p); 860 872 861 873 if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) { … … 870 882 } 871 883 872 void yes_forget_key( gpointer w,void *data)884 void yes_forget_key(void *data) 873 885 { 874 886 OtrlPrivKey *key = (OtrlPrivKey *)data; … … 889 901 char human[54]; 890 902 char *s; 903 pair_t *p; 891 904 892 905 if(!args[3]) { … … 922 935 otrl_privkey_hash_to_human(human, fp->fingerprint); 923 936 s = g_strdup_printf("about to forget fingerprint %s, are you sure?", human); 924 query_add(irc, NULL, s, yes_forget_fingerprint, NULL, fp); 937 p = g_malloc(sizeof(pair_t)); 938 if(!p) 939 return; 940 p->fst = irc; 941 p->snd = fp; 942 query_add(irc, NULL, s, yes_forget_fingerprint, NULL, p); 925 943 g_free(s); 926 944 } … … 931 949 ConnContext *ctx; 932 950 char *s; 951 pair_t *p; 933 952 934 953 /* TODO: allow context specs ("user/proto/account") in 'otr forget contex'? */ … … 952 971 953 972 s = g_strdup_printf("about to forget otr data about %s, are you sure?", args[2]); 954 query_add(irc, NULL, s, yes_forget_context, NULL, ctx); 973 p = g_malloc(sizeof(pair_t)); 974 if(!p) 975 return; 976 p->fst = irc; 977 p->snd = ctx; 978 query_add(irc, NULL, s, yes_forget_context, NULL, p); 955 979 g_free(s); 956 980 } … … 1660 1684 } 1661 1685 1662 void yes_keygen( gpointer w,void *data)1686 void yes_keygen(void *data) 1663 1687 { 1664 1688 account_t *acc = (account_t *)data; -
protocols/jabber/Makefile
reb0714d r9b55485 10 10 11 11 # [SH] Program variables 12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/io.c
reb0714d r9b55485 241 241 } 242 242 243 /* EAGAIN/etc or a successful read. */ 244 return TRUE; 243 if( ssl_pending( jd->ssl ) ) 244 /* OpenSSL empties the TCP buffers completely but may keep some 245 data in its internap buffers. select() won't see that, but 246 ssl_pending() does. */ 247 return jabber_read_callback( data, fd, cond ); 248 else 249 return TRUE; 245 250 } 246 251 … … 521 526 from the server too. */ 522 527 xt_free( jd->xt ); /* In case we're RE-starting. */ 523 jd->xt = xt_new( ic ); 524 jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; 528 jd->xt = xt_new( jabber_handlers, ic ); 525 529 526 530 if( jd->r_inpa <= 0 ) -
protocols/jabber/jabber.c
reb0714d r9b55485 33 33 #include "jabber.h" 34 34 #include "md5.h" 35 #include "base64.h"36 35 37 36 GSList *jabber_connections; 38 37 38 /* First enty is the default */ 39 static const int jabber_port_list[] = { 40 5222, 41 5223, 42 5220, 43 5221, 44 5224, 45 5225, 46 5226, 47 5227, 48 5228, 49 5229, 50 80, 51 443, 52 0 53 }; 54 39 55 static void jabber_init( account_t *acc ) 40 56 { 41 57 set_t *s; 42 43 s = set_add( &acc->set, "port", JABBER_PORT_DEFAULT, set_eval_int, acc ); 58 char str[16]; 59 60 g_snprintf( str, sizeof( str ), "%d", jabber_port_list[0] ); 61 s = set_add( &acc->set, "port", str, set_eval_int, acc ); 44 62 s->flags |= ACC_SET_OFFLINE_ONLY; 45 63 … … 72 90 struct ns_srv_reply *srv = NULL; 73 91 char *connect_to, *s; 92 int i; 74 93 75 94 /* For now this is needed in the _connected() handlers if using … … 177 196 imcb_log( ic, "Connecting" ); 178 197 179 if( set_getint( &acc->set, "port" ) < JABBER_PORT_MIN || 180 set_getint( &acc->set, "port" ) > JABBER_PORT_MAX ) 181 { 182 imcb_log( ic, "Incorrect port number, must be in the %d-%d range", 183 JABBER_PORT_MIN, JABBER_PORT_MAX ); 198 for( i = 0; jabber_port_list[i] > 0; i ++ ) 199 if( set_getint( &acc->set, "port" ) == jabber_port_list[i] ) 200 break; 201 202 if( jabber_port_list[i] == 0 ) 203 { 204 imcb_log( ic, "Illegal port number" ); 184 205 imc_logout( ic, FALSE ); 185 206 return; … … 219 240 } 220 241 242 /* This generates an unfinished md5_state_t variable. Every time we generate 243 an ID, we finish the state by adding a sequence number and take the hash. */ 221 244 static void jabber_generate_id_hash( struct jabber_data *jd ) 222 245 { 223 md5_state_t id_hash; 224 md5_byte_t binbuf[16]; 246 md5_byte_t binbuf[4]; 225 247 char *s; 226 248 227 md5_init( & id_hash);228 md5_append( & id_hash, (unsigned char *) jd->username, strlen( jd->username ) );229 md5_append( & id_hash, (unsigned char *) jd->server, strlen( jd->server ) );249 md5_init( &jd->cached_id_prefix ); 250 md5_append( &jd->cached_id_prefix, (unsigned char *) jd->username, strlen( jd->username ) ); 251 md5_append( &jd->cached_id_prefix, (unsigned char *) jd->server, strlen( jd->server ) ); 230 252 s = set_getstr( &jd->ic->acc->set, "resource" ); 231 md5_append( &id_hash, (unsigned char *) s, strlen( s ) ); 232 random_bytes( binbuf, 16 ); 233 md5_append( &id_hash, binbuf, 16 ); 234 md5_finish( &id_hash, binbuf ); 235 236 s = base64_encode( binbuf, 9 ); 237 jd->cached_id_prefix = g_strdup_printf( "%s%s", JABBER_CACHED_ID, s ); 238 g_free( s ); 253 md5_append( &jd->cached_id_prefix, (unsigned char *) s, strlen( s ) ); 254 random_bytes( binbuf, 4 ); 255 md5_append( &jd->cached_id_prefix, binbuf, 4 ); 239 256 } 240 257 -
protocols/jabber/jabber.h
reb0714d r9b55485 86 86 char *away_message; 87 87 88 char *cached_id_prefix;88 md5_state_t cached_id_prefix; 89 89 GHashTable *node_cache; 90 90 GHashTable *buddies; … … 134 134 135 135 #define JABBER_XMLCONSOLE_HANDLE "xmlconsole" 136 137 #define JABBER_PORT_DEFAULT "5222"138 #define JABBER_PORT_MIN 5220139 #define JABBER_PORT_MAX 5229140 136 141 137 /* Prefixes to use for packet IDs (mainly for IQ packets ATM). Usually the -
protocols/jabber/jabber_util.c
reb0714d r9b55485 23 23 24 24 #include "jabber.h" 25 #include "md5.h" 26 #include "base64.h" 25 27 26 28 static unsigned int next_id = 1; … … 134 136 struct jabber_data *jd = ic->proto_data; 135 137 struct jabber_cache_entry *entry = g_new0( struct jabber_cache_entry, 1 ); 136 char *id; 137 138 id = g_strdup_printf( "%s%05x", jd->cached_id_prefix, ( next_id++ ) & 0xfffff ); 138 md5_state_t id_hash; 139 md5_byte_t id_sum[16]; 140 char *id, *asc_hash; 141 142 next_id ++; 143 144 id_hash = jd->cached_id_prefix; 145 md5_append( &id_hash, (md5_byte_t*) &next_id, sizeof( next_id ) ); 146 md5_finish( &id_hash, id_sum ); 147 asc_hash = base64_encode( id_sum, 12 ); 148 149 id = g_strdup_printf( "%s%s", JABBER_CACHED_ID, asc_hash ); 139 150 xt_add_attr( node, "id", id ); 140 151 g_free( id ); 152 g_free( asc_hash ); 141 153 142 154 entry->node = node; … … 184 196 185 197 if( ( s = xt_find_attr( node, "id" ) ) == NULL || 186 strncmp( s, jd->cached_id_prefix, strlen( jd->cached_id_prefix) ) != 0 )198 strncmp( s, JABBER_CACHED_ID, strlen( JABBER_CACHED_ID ) ) != 0 ) 187 199 { 188 200 /* Silently ignore it, without an ID (or a non-cache … … 196 208 if( entry == NULL ) 197 209 { 210 /* 211 There's no longer an easy way to see if we generated this 212 one or someone else, and there's a ten-minute timeout anyway, 213 so meh. 214 198 215 imcb_log( ic, "Warning: Received %s-%s packet with unknown/expired ID %s!", 199 216 node->name, xt_find_attr( node, "type" ) ? : "(no type)", s ); 217 */ 200 218 } 201 219 else if( entry->func ) … … 246 264 }; 247 265 248 static void jabber_buddy_ask_yes( gpointer w, struct jabber_buddy_ask_data *bla ) 249 { 266 static void jabber_buddy_ask_yes( void *data ) 267 { 268 struct jabber_buddy_ask_data *bla = data; 269 250 270 presence_send_request( bla->ic, bla->handle, "subscribed" ); 251 271 … … 257 277 } 258 278 259 static void jabber_buddy_ask_no( gpointer w, struct jabber_buddy_ask_data *bla ) 260 { 279 static void jabber_buddy_ask_no( void *data ) 280 { 281 struct jabber_buddy_ask_data *bla = data; 282 261 283 presence_send_request( bla->ic, bla->handle, "subscribed" ); 262 284 … … 286 308 len = strlen( orig ); 287 309 new = g_new( char, len + 1 ); 288 for( i = 0; i < len; i ++ ) 310 311 /* So it turns out the /resource part is case sensitive. Yeah, and 312 it's Unicode but feck Unicode. :-P So stop once we see a slash. */ 313 for( i = 0; i < len && orig[i] != '/' ; i ++ ) 289 314 new[i] = tolower( orig[i] ); 315 for( ; orig[i]; i ++ ) 316 new[i] = orig[i]; 290 317 291 318 new[i] = 0; … … 330 357 { 331 358 /* Check for dupes. */ 332 if( g_strcasecmp( bi->resource, s + 1 ) == 0 )359 if( strcmp( bi->resource, s + 1 ) == 0 ) 333 360 { 334 361 *s = '/'; … … 383 410 if( ( s = strchr( jid, '/' ) ) ) 384 411 { 385 int none_found= 0;412 int bare_exists = 0; 386 413 387 414 *s = 0; … … 406 433 /* See if there's an exact match. */ 407 434 for( ; bud; bud = bud->next ) 408 if( g_strcasecmp( bud->resource, s + 1 ) == 0 )435 if( strcmp( bud->resource, s + 1 ) == 0 ) 409 436 break; 410 437 } 411 438 else 412 439 { 413 /* This hack is there to make sure that O_CREAT will 414 work if there's already another resouce present 415 for this JID, even if it's an unknown buddy. This 416 is done to handle conferences properly. */ 417 none_found = 1; 418 /* TODO(wilmer): Find out what I was thinking when I 419 wrote this??? And then fix it. This makes me sad... */ 420 } 421 422 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && ( imcb_find_buddy( ic, jid ) || !none_found ) ) 440 /* This variable tells the if down here that the bare 441 JID already exists and we should feel free to add 442 more resources, if the caller asked for that. */ 443 bare_exists = 1; 444 } 445 446 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && 447 ( !bare_exists || imcb_find_buddy( ic, jid ) ) ) 423 448 { 424 449 *s = '/'; … … 445 470 /* We want an exact match, so in thise case there shouldn't be a /resource. */ 446 471 return NULL; 447 else if( ( bud->resource == NULL || bud->next == NULL ))472 else if( bud->resource == NULL || bud->next == NULL ) 448 473 /* No need for selection if there's only one option. */ 449 474 return bud; … … 521 546 matches), removing it is simple. (And the hash reference 522 547 should be removed too!) */ 523 if( bud->next == NULL && ( ( s == NULL || bud->resource == NULL ) || g_strcasecmp( bud->resource, s + 1 ) == 0 ) ) 548 if( bud->next == NULL && 549 ( ( s == NULL && bud->resource == NULL ) || 550 ( bud->resource && s && strcmp( bud->resource, s + 1 ) == 0 ) ) ) 524 551 { 525 552 g_hash_table_remove( jd->buddies, bud->bare_jid ); … … 544 571 { 545 572 for( bi = bud, prev = NULL; bi; bi = (prev=bi)->next ) 546 if( g_strcasecmp( bi->resource, s + 1 ) == 0 )573 if( strcmp( bi->resource, s + 1 ) == 0 ) 547 574 break; 548 575 -
protocols/jabber/message.c
reb0714d r9b55485 49 49 { 50 50 GString *fullmsg = g_string_new( "" ); 51 52 for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next ) 53 { 54 char *ns = xt_find_attr( c, "xmlns" ), *room; 55 struct xt_node *inv, *reason; 56 57 if( strcmp( ns, XMLNS_MUC_USER ) == 0 && 58 ( inv = xt_find_node( c->children, "invite" ) ) ) 59 { 60 room = from; 61 from = xt_find_attr( inv, "from" ) ? : from; 62 63 g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Invitation to chatroom %s >>\n", room ); 64 if( ( reason = xt_find_node( inv->children, "reason" ) ) && reason->text_len > 0 ) 65 g_string_append( fullmsg, reason->text ); 66 } 67 } 51 68 52 69 if( ( s = strchr( from, '/' ) ) ) -
protocols/msn/msn.h
reb0714d r9b55485 29 29 #define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r" 30 30 31 #ifdef DEBUG 31 #ifdef DEBUG_MSN 32 32 #define debug( text... ) imcb_log( ic, text ); 33 33 #else -
protocols/msn/msn_util.c
reb0714d r9b55485 90 90 }; 91 91 92 static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla ) 93 { 92 static void msn_buddy_ask_yes( void *data ) 93 { 94 struct msn_buddy_ask_data *bla = data; 95 94 96 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname ); 95 97 … … 102 104 } 103 105 104 static void msn_buddy_ask_no( gpointer w, struct msn_buddy_ask_data *bla ) 105 { 106 static void msn_buddy_ask_no( void *data ) 107 { 108 struct msn_buddy_ask_data *bla = data; 109 106 110 msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname ); 107 111 -
protocols/msn/ns.c
reb0714d r9b55485 34 34 static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); 35 35 36 static void msn_auth_got_passport_ id( struct passport_reply *rep);36 static void msn_auth_got_passport_token( struct msn_auth_data *mad ); 37 37 38 38 gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) … … 178 178 179 179 debug( "Connecting to a new switchboard with key %s", cmd[5] ); 180 sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW ); 180 181 if( ( sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW ) ) == NULL ) 182 { 183 /* Although this isn't strictly fatal for the NS connection, it's 184 definitely something serious (we ran out of file descriptors?). */ 185 imcb_error( ic, "Could not create new switchboard" ); 186 imc_logout( ic, TRUE ); 187 return( 0 ); 188 } 181 189 182 190 if( md->msgq ) … … 214 222 { 215 223 /* Time for some Passport black magic... */ 216 if( !passport_get_ id( msn_auth_got_passport_id, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )224 if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) ) 217 225 { 218 226 imcb_error( ic, "Error while contacting Passport server" ); … … 270 278 if( num_parts == 5 ) 271 279 { 280 int i, groupcount; 281 282 groupcount = atoi( cmd[4] ); 283 if( groupcount > 0 ) 284 { 285 /* valgrind says this is leaking memory, I'm guessing 286 that this happens during server redirects. */ 287 if( md->grouplist ) 288 { 289 for( i = 0; i < md->groupcount; i ++ ) 290 g_free( md->grouplist[i] ); 291 g_free( md->grouplist ); 292 } 293 294 md->groupcount = groupcount; 295 md->grouplist = g_new0( char *, md->groupcount ); 296 } 297 272 298 md->buddycount = atoi( cmd[3] ); 273 md->groupcount = atoi( cmd[4] );274 if( md->groupcount > 0 )275 md->grouplist = g_new0( char *, md->groupcount );276 277 299 if( !*cmd[3] || md->buddycount == 0 ) 278 300 msn_logged_in( ic ); … … 468 490 debug( "Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4] ); 469 491 470 sb = msn_sb_create( ic, server, port, cmd[4], session ); 471 sb->who = g_strdup( cmd[5] ); 492 if( ( sb = msn_sb_create( ic, server, port, cmd[4], session ) ) == NULL ) 493 { 494 /* Although this isn't strictly fatal for the NS connection, it's 495 definitely something serious (we ran out of file descriptors?). */ 496 imcb_error( ic, "Could not create new switchboard" ); 497 imc_logout( ic, TRUE ); 498 return( 0 ); 499 } 500 else 501 { 502 sb->who = g_strdup( cmd[5] ); 503 } 472 504 } 473 505 else if( strcmp( cmd[0], "ADD" ) == 0 ) … … 647 679 imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders ); 648 680 } 681 682 g_free( inbox ); 683 g_free( folders ); 649 684 } 650 685 else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 ) … … 674 709 } 675 710 676 static void msn_auth_got_passport_ id( struct passport_reply *rep)711 static void msn_auth_got_passport_token( struct msn_auth_data *mad ) 677 712 { 678 struct im_connection *ic = rep->data; 679 struct msn_data *md = ic->proto_data; 680 char *key = rep->result; 681 char buf[1024]; 682 683 if( key == NULL ) 684 { 685 imcb_error( ic, "Error during Passport authentication (%s)", 686 rep->error_string ? rep->error_string : "Unknown error" ); 713 struct im_connection *ic = mad->data; 714 struct msn_data *md; 715 716 /* Dead connection? */ 717 if( g_slist_find( msn_connections, ic ) == NULL ) 718 return; 719 720 md = ic->proto_data; 721 if( mad->token ) 722 { 723 char buf[1024]; 724 725 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token ); 726 msn_write( ic, buf, strlen( buf ) ); 727 } 728 else 729 { 730 imcb_error( ic, "Error during Passport authentication: %s", mad->error ); 687 731 imc_logout( ic, TRUE ); 688 732 } 689 else690 {691 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );692 msn_write( ic, buf, strlen( buf ) );693 }694 733 } -
protocols/msn/passport.c
reb0714d r9b55485 1 /* passport.c1 /** passport.c 2 2 * 3 * Functions to login to microsoft passport service for Messenger 4 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be> 5 * Copyright (C) 2004 Wilmer van der Gaast <wilmer@gaast.net> 3 * Functions to login to Microsoft Passport service for Messenger 4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net> 6 5 * 7 6 * This program is free software; you can redistribute it and/or modify … … 24 23 #include "msn.h" 25 24 #include "bitlbee.h" 25 #include "url.h" 26 #include "misc.h" 27 #include "xmltree.h" 26 28 #include <ctype.h> 27 29 #include <errno.h> 28 30 29 #define MSN_BUF_LEN 8192 31 static int passport_get_token_real( struct msn_auth_data *mad ); 32 static void passport_get_token_ready( struct http_request *req ); 30 33 31 static char *prd_cached = NULL; 32 33 static int passport_get_id_real( gpointer func, gpointer data, char *header ); 34 static void passport_get_id_ready( struct http_request *req ); 35 36 static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header ); 37 static void passport_retrieve_dalogin_ready( struct http_request *req ); 38 39 static char *passport_create_header( char *cookie, char *email, char *pwd ); 40 static void destroy_reply( struct passport_reply *rep ); 41 42 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ) 34 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie ) 43 35 { 44 char *header = passport_create_header( cookie, username, password ); 36 struct msn_auth_data *mad = g_new0( struct msn_auth_data, 1 ); 37 int i; 45 38 46 if( prd_cached == NULL ) 47 return passport_retrieve_dalogin( func, data, header ); 48 else 49 return passport_get_id_real( func, data, header ); 39 mad->username = g_strdup( username ); 40 mad->password = g_strdup( password ); 41 mad->cookie = g_strdup( cookie ); 42 43 mad->callback = func; 44 mad->data = data; 45 46 mad->url = g_strdup( SOAP_AUTHENTICATION_URL ); 47 mad->ttl = 3; /* Max. # of redirects. */ 48 49 /* HTTP-escape stuff and s/,/&/ */ 50 http_decode( mad->cookie ); 51 for( i = 0; mad->cookie[i]; i ++ ) 52 if( mad->cookie[i] == ',' ) 53 mad->cookie[i] = '&'; 54 55 /* Microsoft doesn't allow password longer than 16 chars and silently 56 fails authentication if you give the "full version" of your passwd. */ 57 if( strlen( mad->password ) > MAX_PASSPORT_PWLEN ) 58 mad->password[MAX_PASSPORT_PWLEN] = 0; 59 60 return passport_get_token_real( mad ); 50 61 } 51 62 52 static int passport_get_ id_real( gpointer func, gpointer data, char *header)63 static int passport_get_token_real( struct msn_auth_data *mad ) 53 64 { 54 struct passport_reply *rep; 55 char *server, *dummy, *reqs; 65 char *post_payload, *post_request; 56 66 struct http_request *req; 67 url_t url; 57 68 58 rep = g_new0( struct passport_reply, 1 ); 59 rep->data = data; 60 rep->func = func; 61 rep->header = header; 69 url_set( &url, mad->url ); 62 70 63 server = g_strdup( prd_cached ); 64 dummy = strchr( server, '/' ); 71 post_payload = g_markup_printf_escaped( SOAP_AUTHENTICATION_PAYLOAD, 72 mad->username, 73 mad->password, 74 mad->cookie ); 65 75 66 if( dummy == NULL ) 67 { 68 destroy_reply( rep ); 69 return( 0 ); 70 } 76 post_request = g_strdup_printf( SOAP_AUTHENTICATION_REQUEST, 77 url.file, url.host, 78 (int) strlen( post_payload ), 79 post_payload ); 80 81 req = http_dorequest( url.host, url.port, 1, post_request, 82 passport_get_token_ready, mad ); 71 83 72 reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header ); 84 g_free( post_request ); 85 g_free( post_payload ); 73 86 74 *dummy = 0; 75 req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep ); 76 77 g_free( server ); 78 g_free( reqs ); 79 80 if( req == NULL ) 81 destroy_reply( rep ); 82 83 return( req != NULL ); 87 return req != NULL; 84 88 } 85 89 86 static void passport_get_id_ready( struct http_request *req ) 90 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data ); 91 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data ); 92 93 static const struct xt_handler_entry passport_xt_handlers[] = { 94 { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", passport_xt_extract_token }, 95 { "S:Fault", "S:Envelope", passport_xt_handle_fault }, 96 { NULL, NULL, NULL } 97 }; 98 99 static void passport_get_token_ready( struct http_request *req ) 87 100 { 88 struct passport_reply *rep = req->data; 101 struct msn_auth_data *mad = req->data; 102 struct xt_parser *parser; 89 103 90 if( !g_slist_find( msn_connections, rep->data ) ) 104 g_free( mad->url ); 105 g_free( mad->error ); 106 mad->url = mad->error = NULL; 107 108 if( req->status_code == 200 ) 91 109 { 92 destroy_reply( rep ); 93 return; 94 } 95 96 if( req->finished && req->reply_headers && req->status_code == 200 ) 97 { 98 char *dummy; 99 100 if( ( dummy = strstr( req->reply_headers, "from-PP='" ) ) ) 101 { 102 char *responseend; 103 104 dummy += strlen( "from-PP='" ); 105 responseend = strchr( dummy, '\'' ); 106 if( responseend ) 107 *responseend = 0; 108 109 rep->result = g_strdup( dummy ); 110 } 111 else 112 { 113 rep->error_string = g_strdup( "Could not parse Passport server response" ); 114 } 110 parser = xt_new( passport_xt_handlers, mad ); 111 xt_feed( parser, req->reply_body, req->body_size ); 112 xt_handle( parser, NULL, -1 ); 113 xt_free( parser ); 115 114 } 116 115 else 117 116 { 118 rep->error_string = g_strdup_printf( "HTTP error: %s",119 req->status_string ? req->status_string : "Unknown error" );117 mad->error = g_strdup_printf( "HTTP error %d (%s)", req->status_code, 118 req->status_string ? req->status_string : "unknown" ); 120 119 } 121 120 122 rep->func( rep ); 123 destroy_reply( rep ); 121 if( mad->error == NULL && mad->token == NULL ) 122 mad->error = g_strdup( "Could not parse Passport server response" ); 123 124 if( mad->url && mad->token == NULL ) 125 { 126 passport_get_token_real( mad ); 127 } 128 else 129 { 130 mad->callback( mad ); 131 132 g_free( mad->url ); 133 g_free( mad->username ); 134 g_free( mad->password ); 135 g_free( mad->cookie ); 136 g_free( mad->token ); 137 g_free( mad->error ); 138 g_free( mad ); 139 } 124 140 } 125 141 126 static char *passport_create_header( char *cookie, char *email, char *pwd)142 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data ) 127 143 { 128 char *buffer; 129 char *currenttoken; 130 char *email_enc, *pwd_enc; 144 struct msn_auth_data *mad = data; 145 char *s; 131 146 132 currenttoken = strstr( cookie, "lc=" ); 133 if( currenttoken == NULL ) 134 return NULL; 147 if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 ) 148 mad->token = g_memdup( node->text, node->text_len + 1 ); 135 149 136 email_enc = g_new0( char, strlen( email ) * 3 + 1 ); 137 strcpy( email_enc, email ); 138 http_encode( email_enc ); 139 140 pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 ); 141 strcpy( pwd_enc, pwd ); 142 http_encode( pwd_enc ); 143 144 buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET," 145 "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom," 146 "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc, 147 currenttoken ); 148 149 g_free( email_enc ); 150 g_free( pwd_enc ); 151 152 return buffer; 150 return XT_HANDLED; 153 151 } 154 152 155 static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header)153 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data ) 156 154 { 157 struct passport_reply *rep = g_new0( struct passport_reply, 1 ); 158 struct http_request *req; 155 struct msn_auth_data *mad = data; 156 struct xt_node *code = xt_find_node( node->children, "faultcode" ); 157 struct xt_node *string = xt_find_node( node->children, "faultstring" ); 158 struct xt_node *redirect = xt_find_node( node->children, "psf:redirectUrl" ); 159 159 160 rep->data = data; 161 rep->func = func; 162 rep->header = header; 160 if( redirect && redirect->text_len && mad->ttl-- > 0 ) 161 mad->url = g_memdup( redirect->text, redirect->text_len + 1 ); 163 162 164 req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep ); 163 if( code == NULL || code->text_len == 0 ) 164 mad->error = g_strdup( "Unknown error" ); 165 else 166 mad->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ? 167 string->text : "no description available" ); 165 168 166 if( !req ) 167 destroy_reply( rep ); 168 169 return( req != NULL ); 169 return XT_HANDLED; 170 170 } 171 172 static void passport_retrieve_dalogin_ready( struct http_request *req )173 {174 struct passport_reply *rep = req->data;175 char *dalogin;176 char *urlend;177 178 if( !g_slist_find( msn_connections, rep->data ) )179 {180 destroy_reply( rep );181 return;182 }183 184 if( !req->finished || !req->reply_headers || req->status_code != 200 )185 {186 rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",187 req->status_string ? req->status_string : "Unknown error" );188 goto failure;189 }190 191 dalogin = strstr( req->reply_headers, "DALogin=" );192 193 if( !dalogin )194 {195 rep->error_string = g_strdup( "Parse error while fetching DALogin" );196 goto failure;197 }198 199 dalogin += strlen( "DALogin=" );200 urlend = strchr( dalogin, ',' );201 if( urlend )202 *urlend = 0;203 204 /* strip the http(s):// part from the url */205 urlend = strstr( urlend, "://" );206 if( urlend )207 dalogin = urlend + strlen( "://" );208 209 if( prd_cached == NULL )210 prd_cached = g_strdup( dalogin );211 212 if( passport_get_id_real( rep->func, rep->data, rep->header ) )213 {214 rep->header = NULL;215 destroy_reply( rep );216 return;217 }218 219 failure:220 rep->func( rep );221 destroy_reply( rep );222 }223 224 static void destroy_reply( struct passport_reply *rep )225 {226 g_free( rep->result );227 g_free( rep->header );228 g_free( rep->error_string );229 g_free( rep );230 } -
protocols/msn/passport.h
reb0714d r9b55485 1 #ifndef __PASSPORT_H__2 #define __PASSPORT_H__3 1 /* passport.h 4 2 * 5 * Functions to login to Microsoft Passport Service for Messenger 6 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>, 7 * Wilmer van der Gaast <wilmer@gaast.net> 3 * Functions to login to Microsoft Passport service for Messenger 4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net> 8 5 * 9 6 * This program is free software; you can redistribute it and/or modify … … 18 15 * You should have received a copy of the GNU General Public License 19 16 * along with this program; if not, write to the Free Software 20 * 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 18 */ 19 20 /* Thanks to http://msnpiki.msnfanatic.com/index.php/MSNP13:SOAPTweener 21 for the specs! */ 22 23 #ifndef __PASSPORT_H__ 24 #define __PASSPORT_H__ 22 25 23 26 #include <stdio.h> … … 33 36 #include "nogaim.h" 34 37 35 struct passport_reply 38 #define MAX_PASSPORT_PWLEN 16 39 40 struct msn_auth_data 36 41 { 37 void (*func)( struct passport_reply * ); 38 void *data; 39 char *result; 40 char *header; 41 char *error_string; 42 char *url; 43 int ttl; 44 45 char *username; 46 char *password; 47 char *cookie; 48 49 /* The end result, the only thing we'll really be interested in 50 once finished. */ 51 char *token; 52 char *error; /* Yeah, or that... */ 53 54 void (*callback)( struct msn_auth_data *mad ); 55 gpointer data; 42 56 }; 43 57 44 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ); 58 #define SOAP_AUTHENTICATION_URL "https://loginnet.passport.com/RST.srf" 59 60 #define SOAP_AUTHENTICATION_REQUEST \ 61 "POST %s HTTP/1.0\r\n" \ 62 "Accept: text/*\r\n" \ 63 "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ 64 "Host: %s\r\n" \ 65 "Content-Length: %d\r\n" \ 66 "Cache-Control: no-cache\r\n" \ 67 "\r\n" \ 68 "%s" 69 70 #define SOAP_AUTHENTICATION_PAYLOAD \ 71 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ 72 "<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \ 73 "<Header>" \ 74 "<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">" \ 75 "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \ 76 "<ps:BinaryVersion>4</ps:BinaryVersion>" \ 77 "<ps:UIVersion>1</ps:UIVersion>" \ 78 "<ps:Cookies></ps:Cookies>" \ 79 "<ps:RequestParams>AQAAAAIAAABsYwQAAAAzMDg0</ps:RequestParams>" \ 80 "</ps:AuthInfo>" \ 81 "<wsse:Security>" \ 82 "<wsse:UsernameToken Id=\"user\">" \ 83 "<wsse:Username>%s</wsse:Username>" \ 84 "<wsse:Password>%s</wsse:Password>" \ 85 "</wsse:UsernameToken>" \ 86 "</wsse:Security>" \ 87 "</Header>" \ 88 "<Body>" \ 89 "<ps:RequestMultipleSecurityTokens xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"RSTS\">" \ 90 "<wst:RequestSecurityToken Id=\"RST0\">" \ 91 "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ 92 "<wsp:AppliesTo>" \ 93 "<wsa:EndpointReference>" \ 94 "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \ 95 "</wsa:EndpointReference>" \ 96 "</wsp:AppliesTo>" \ 97 "</wst:RequestSecurityToken>" \ 98 "<wst:RequestSecurityToken Id=\"RST1\">" \ 99 "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ 100 "<wsp:AppliesTo>" \ 101 "<wsa:EndpointReference>" \ 102 "<wsa:Address>messenger.msn.com</wsa:Address>" \ 103 "</wsa:EndpointReference>" \ 104 "</wsp:AppliesTo>" \ 105 "<wsse:PolicyReference URI=\"?%s\"></wsse:PolicyReference>" \ 106 "</wst:RequestSecurityToken>" \ 107 "</ps:RequestMultipleSecurityTokens>" \ 108 "</Body>" \ 109 "</Envelope>" 110 111 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie ); 45 112 46 113 #endif /* __PASSPORT_H__ */ -
protocols/nogaim.c
reb0714d r9b55485 343 343 /* dialogs.c */ 344 344 345 void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont ) 345 void imcb_ask( struct im_connection *ic, char *msg, void *data, 346 query_callback doit, query_callback dont ) 346 347 { 347 348 query_add( ic->irc, ic, msg, doit, dont, data ); … … 495 496 }; 496 497 497 void show_got_added_no( gpointer w, struct show_got_added_data*data )498 { 499 g_free( data->handle );498 void show_got_added_no( void *data ) 499 { 500 g_free( ((struct show_got_added_data*)data)->handle ); 500 501 g_free( data ); 501 502 } 502 503 503 void show_got_added_yes( gpointer w, struct show_got_added_data *data ) 504 { 505 data->ic->acc->prpl->add_buddy( data->ic, data->handle, NULL ); 506 /* imcb_add_buddy( data->ic, NULL, data->handle, data->handle ); */ 507 508 return show_got_added_no( w, data ); 504 void show_got_added_yes( void *data ) 505 { 506 struct show_got_added_data *sga = data; 507 508 sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL ); 509 /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */ 510 511 return show_got_added_no( data ); 509 512 } 510 513 -
protocols/nogaim.h
reb0714d r9b55485 42 42 #include "account.h" 43 43 #include "proxy.h" 44 #include "query.h" 44 45 #include "md5.h" 45 46 #define BUF_LEN MSG_LEN47 #define BUF_LONG ( BUF_LEN * 2 )48 #define MSG_LEN 204849 #define BUF_LEN MSG_LEN50 46 51 47 #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ … … 265 261 * - 'doit' or 'dont' will be called depending of the answer of the user. 266 262 */ 267 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont );263 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont ); 268 264 G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ); 269 265 -
protocols/oscar/oscar.c
reb0714d r9b55485 60 60 61 61 #define OSCAR_GROUP "Friends" 62 63 #define BUF_LEN 2048 64 #define BUF_LONG ( BUF_LEN * 2 ) 62 65 63 66 /* Don't know if support for UTF8 is really working. For now it's UTF16 here. … … 240 243 }; 241 244 static int msgerrreasonlen = 25; 245 246 /* Hurray, this function is NOT thread-safe \o/ */ 247 static char *normalize(const char *s) 248 { 249 static char buf[BUF_LEN]; 250 char *t, *u; 251 int x = 0; 252 253 g_return_val_if_fail((s != NULL), NULL); 254 255 u = t = g_strdup(s); 256 257 strcpy(t, s); 258 g_strdown(t); 259 260 while (*t && (x < BUF_LEN - 1)) { 261 if (*t != ' ' && *t != '!') { 262 buf[x] = *t; 263 x++; 264 } 265 t++; 266 } 267 buf[x] = '\0'; 268 g_free(u); 269 return buf; 270 } 242 271 243 272 static gboolean oscar_callback(gpointer data, gint source, … … 1002 1031 } 1003 1032 1004 tmp = g_strdup(normalize(ic->acc->user)); 1005 if (!strcmp(tmp, normalize(info->sn))) 1033 if (!aim_sncmp(ic->acc->user, info->sn)) 1006 1034 g_snprintf(ic->displayname, sizeof(ic->displayname), "%s", info->sn); 1007 g_free(tmp); 1008 1009 imcb_buddy_status(ic, info->sn, flags, state_string, NULL); 1010 /* imcb_buddy_times(ic, info->sn, signon, time_idle); */ 1035 1036 tmp = normalize(info->sn); 1037 imcb_buddy_status(ic, tmp, flags, state_string, NULL); 1038 /* imcb_buddy_times(ic, tmp, signon, time_idle); */ 1039 1011 1040 1012 1041 return 1; … … 1022 1051 va_end(ap); 1023 1052 1024 imcb_buddy_status(ic, info->sn, 0, NULL, NULL );1053 imcb_buddy_status(ic, normalize(info->sn), 0, NULL, NULL ); 1025 1054 1026 1055 return 1; … … 1078 1107 1079 1108 strip_linefeed(tmp); 1080 imcb_buddy_msg(ic, userinfo->sn, tmp, flags, 0);1109 imcb_buddy_msg(ic, normalize(userinfo->sn), tmp, flags, 0); 1081 1110 g_free(tmp); 1082 1111 … … 1084 1113 } 1085 1114 1086 void oscar_accept_chat( gpointer w, struct aim_chat_invitation * inv);1087 void oscar_reject_chat( gpointer w, struct aim_chat_invitation * inv);1115 void oscar_accept_chat(void *data); 1116 void oscar_reject_chat(void *data); 1088 1117 1089 1118 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) { … … 1119 1148 } 1120 1149 1121 static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) { 1150 static void gaim_icq_authgrant(void *data_) { 1151 struct icq_auth *data = data_; 1122 1152 char *uin, message; 1123 1153 struct oscar_data *od = (struct oscar_data *)data->ic->proto_data; … … 1134 1164 } 1135 1165 1136 static void gaim_icq_authdeny(gpointer w, struct icq_auth *data) { 1166 static void gaim_icq_authdeny(void *data_) { 1167 struct icq_auth *data = data_; 1137 1168 char *uin, *message; 1138 1169 struct oscar_data *od = (struct oscar_data *)data->ic->proto_data; … … 1175 1206 message = g_strdup(args->msg); 1176 1207 strip_linefeed(message); 1177 imcb_buddy_msg(ic, uin, message, 0, 0);1208 imcb_buddy_msg(ic, normalize(uin), message, 0, 0); 1178 1209 g_free(uin); 1179 1210 g_free(message); … … 1194 1225 1195 1226 strip_linefeed(message); 1196 imcb_buddy_msg(ic, uin, message, 0, 0);1227 imcb_buddy_msg(ic, normalize(uin), message, 0, 0); 1197 1228 g_free(uin); 1198 1229 g_free(m); … … 1469 1500 1470 1501 for (i = 0; i < count; i++) 1471 imcb_chat_add_buddy(c->cnv, info[i].sn);1502 imcb_chat_add_buddy(c->cnv, normalize(info[i].sn)); 1472 1503 1473 1504 return 1; … … 1492 1523 1493 1524 for (i = 0; i < count; i++) 1494 imcb_chat_remove_buddy(c->cnv, info[i].sn, NULL);1525 imcb_chat_remove_buddy(c->cnv, normalize(info[i].sn), NULL); 1495 1526 1496 1527 return 1; … … 1543 1574 tmp = g_malloc(BUF_LONG); 1544 1575 g_snprintf(tmp, BUF_LONG, "%s", msg); 1545 imcb_chat_msg(ccon->cnv, info->sn, tmp, 0, 0);1576 imcb_chat_msg(ccon->cnv, normalize(info->sn), tmp, 0, 0); 1546 1577 g_free(tmp); 1547 1578 … … 1756 1787 g_snprintf(sender, sizeof(sender), "%u", msg->sender); 1757 1788 strip_linefeed(dialog_msg); 1758 imcb_buddy_msg(ic, sender, dialog_msg, 0, t);1789 imcb_buddy_msg(ic, normalize(sender), dialog_msg, 0, t); 1759 1790 g_free(dialog_msg); 1760 1791 } break; … … 1777 1808 1778 1809 strip_linefeed(dialog_msg); 1779 imcb_buddy_msg(ic, sender, dialog_msg, 0, t);1810 imcb_buddy_msg(ic, normalize(sender), dialog_msg, 0, t); 1780 1811 g_free(dialog_msg); 1781 1812 g_free(m); … … 2015 2046 struct aim_ssi_item *curitem; 2016 2047 int tmp; 2048 char *nrm; 2017 2049 2018 2050 /* Add from server list to local list */ 2019 2051 tmp = 0; 2020 2052 for (curitem=sess->ssi.items; curitem; curitem=curitem->next) { 2053 nrm = curitem->name ? normalize(curitem->name) : NULL; 2054 2021 2055 switch (curitem->type) { 2022 2056 case 0x0000: /* Buddy */ 2023 if ((curitem->name) && (!imcb_find_buddy(ic, curitem->name))) {2057 if ((curitem->name) && (!imcb_find_buddy(ic, nrm))) { 2024 2058 char *realname = NULL; 2025 2059 … … 2027 2061 realname = aim_gettlv_str(curitem->data, 0x0131, 1); 2028 2062 2029 imcb_add_buddy(ic, curitem->name, NULL);2063 imcb_add_buddy(ic, nrm, NULL); 2030 2064 2031 2065 if (realname) { 2032 imcb_buddy_nick_hint(ic, curitem->name, realname);2033 imcb_rename_buddy(ic, curitem->name, realname);2066 imcb_buddy_nick_hint(ic, nrm, realname); 2067 imcb_rename_buddy(ic, nrm, realname); 2034 2068 g_free(realname); 2035 2069 } … … 2043 2077 if (!list) { 2044 2078 char *name; 2045 name = g_strdup(n ormalize(curitem->name));2079 name = g_strdup(nrm); 2046 2080 ic->permit = g_slist_append(ic->permit, name); 2047 2081 tmp++; … … 2056 2090 if (!list) { 2057 2091 char *name; 2058 name = g_strdup(n ormalize(curitem->name));2092 name = g_strdup(nrm); 2059 2093 ic->deny = g_slist_append(ic->deny, name); 2060 2094 tmp++; … … 2118 2152 if( st == 0x00 ) 2119 2153 { 2120 imcb_add_buddy( sess->aux_data, list, NULL );2154 imcb_add_buddy( sess->aux_data, normalize(list), NULL ); 2121 2155 } 2122 2156 else if( st == 0x0E ) … … 2448 2482 if(type2 == 0x0002) { 2449 2483 /* User is typing */ 2450 imcb_buddy_typing(ic, sn, OPT_TYPING);2484 imcb_buddy_typing(ic, normalize(sn), OPT_TYPING); 2451 2485 } 2452 2486 else if (type2 == 0x0001) { 2453 2487 /* User has typed something, but is not actively typing (stale) */ 2454 imcb_buddy_typing(ic, sn, OPT_THINKING);2488 imcb_buddy_typing(ic, normalize(sn), OPT_THINKING); 2455 2489 } 2456 2490 else { 2457 2491 /* User has stopped typing */ 2458 imcb_buddy_typing(ic, sn, 0);2492 imcb_buddy_typing(ic, normalize(sn), 0); 2459 2493 } 2460 2494 … … 2588 2622 } 2589 2623 2590 void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv) 2591 { 2624 void oscar_accept_chat(void *data) 2625 { 2626 struct aim_chat_invitation * inv = data; 2627 2592 2628 oscar_chat_join(inv->ic, inv->name, NULL, NULL); 2593 2629 g_free(inv->name); … … 2595 2631 } 2596 2632 2597 void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv) 2598 { 2633 void oscar_reject_chat(void *data) 2634 { 2635 struct aim_chat_invitation * inv = data; 2636 2599 2637 g_free(inv->name); 2600 2638 g_free(inv); -
protocols/yahoo/libyahoo2.c
reb0714d r9b55485 69 69 #ifdef __MINGW32__ 70 70 # include <winsock2.h> 71 # define write(a,b,c) send(a,b,c,0)72 # define read(a,b,c) recv(a,b,c,0)73 71 #endif 74 72 … … 381 379 382 380 /* call repeatedly to get the next one */ 383 /*384 381 static struct yahoo_input_data * find_input_by_id(int id) 385 382 { … … 392 389 return NULL; 393 390 } 394 */395 391 396 392 static struct yahoo_input_data * find_input_by_id_and_webcam_user(int id, const char * who) … … 737 733 738 734 memcpy(data + pos, "YMSG", 4); pos += 4; 739 pos += yahoo_put16(data + pos, 0x0 a00);735 pos += yahoo_put16(data + pos, 0x000c); 740 736 pos += yahoo_put16(data + pos, 0x0000); 741 737 pos += yahoo_put16(data + pos, pktlen + extra_pad); … … 797 793 { 798 794 struct yahoo_data *yd = find_conn_by_id(id); 795 799 796 if(!yd) 800 797 return; … … 3166 3163 3167 3164 LOG(("write callback: id=%d fd=%d data=%p", id, fd, data)); 3168 if(!yid || !yid->txqueues )3165 if(!yid || !yid->txqueues || !find_conn_by_id(id)) 3169 3166 return -2; 3170 3167 … … 3351 3348 break; 3352 3349 case 5: 3353 if( cp != "\005")3350 if(strcmp(cp, "5") != 0) 3354 3351 yct->location = cp; 3355 3352 k = 0; … … 3842 3839 } 3843 3840 3844 3845 /* do { 3841 do { 3846 3842 yahoo_input_close(yid); 3847 } while((yid = find_input_by_id(id)));*/ 3848 3843 } while((yid = find_input_by_id(id))); 3849 3844 } 3850 3845 -
protocols/yahoo/yahoo.c
reb0714d r9b55485 163 163 g_slist_free( yd->buddygroups ); 164 164 165 if( yd->logged_in ) 166 yahoo_logoff( yd->y2_id ); 167 else 168 yahoo_close( yd->y2_id ); 165 yahoo_logoff( yd->y2_id ); 169 166 170 167 g_free( yd ); … … 315 312 struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data; 316 313 317 yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );314 yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" ); 318 315 } 319 316 … … 454 451 { 455 452 struct byahoo_write_ready_data *d = data; 456 457 if( !byahoo_get_ic_by_id( d->id ) )458 /* WTF doesn't libyahoo clean this up? */459 return FALSE;460 453 461 454 yahoo_write_ready( d->id, d->fd, d->data ); … … 798 791 } 799 792 800 static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv ) 801 { 793 static void byahoo_accept_conf( void *data ) 794 { 795 struct byahoo_conf_invitation *inv = data; 796 802 797 yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name ); 803 798 imcb_chat_add_buddy( inv->c, inv->ic->acc->user ); … … 806 801 } 807 802 808 static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv ) 809 { 803 static void byahoo_reject_conf( void *data ) 804 { 805 struct byahoo_conf_invitation *inv = data; 806 810 807 yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" ); 811 808 imcb_chat_free( inv->c ); -
protocols/yahoo/yahoo_httplib.c
reb0714d r9b55485 51 51 #ifdef __MINGW32__ 52 52 # include <winsock2.h> 53 # define write(a,b,c) send(a,b,c,0)54 # define read(a,b,c) recv(a,b,c,0)55 53 # define snprintf _snprintf 56 54 #endif -
query.c
reb0714d r9b55485 30 30 static query_t *query_default( irc_t *irc ); 31 31 32 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data ) 32 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, 33 query_callback yes, query_callback no, void *data ) 33 34 { 34 35 query_t *q = g_new0( query_t, 1 ); … … 143 144 if( ans ) 144 145 { 145 if( q->ic)146 if( q->ic ) 146 147 imcb_log( q->ic, "Accepted: %s", q->question ); 147 148 else 148 149 irc_usermsg( irc, "Accepted: %s", q->question ); 149 if( q->yes)150 q->yes( q-> ic ? (gpointer)q->ic : (gpointer)irc, q->data );150 if( q->yes ) 151 q->yes( q->data ); 151 152 } 152 153 else 153 154 { 154 if( q->ic)155 if( q->ic ) 155 156 imcb_log( q->ic, "Rejected: %s", q->question ); 156 157 else 157 158 irc_usermsg( irc, "Rejected: %s", q->question ); 158 if( q->no)159 q->no( q-> ic ? (gpointer)q->ic : (gpointer)irc, q->data );159 if( q->no ) 160 q->no( q->data ); 160 161 } 161 162 q->data = NULL; -
query.h
reb0714d r9b55485 27 27 #define _QUERY_H 28 28 29 typedef void (*query_callback) ( void *data ); 30 29 31 typedef struct query 30 32 { 31 33 struct im_connection *ic; 32 34 char *question; 33 void (* yes) ( gpointer w, void *data ); 34 void (* no) ( gpointer w, void *data ); 35 query_callback yes, no; 35 36 void *data; 36 37 struct query *next; 37 38 } query_t; 38 39 39 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data ); 40 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, 41 query_callback yes, query_callback no, void *data ); 40 42 void query_del( irc_t *irc, query_t *q ); 41 43 void query_del_by_conn( irc_t *irc, struct im_connection *ic ); -
root_commands.c
reb0714d r9b55485 205 205 } 206 206 207 struct cmd_account_del_data 208 { 209 account_t *a; 210 irc_t *irc; 211 }; 212 213 void cmd_account_del_yes( void *data ) 214 { 215 struct cmd_account_del_data *cad = data; 216 account_t *a; 217 218 for( a = cad->irc->accounts; a && a != cad->a; a = a->next ); 219 220 if( a == NULL ) 221 { 222 irc_usermsg( cad->irc, "Account already deleted" ); 223 } 224 else if( a->ic ) 225 { 226 irc_usermsg( cad->irc, "Account is still logged in, can't delete" ); 227 } 228 else 229 { 230 account_del( cad->irc, a ); 231 irc_usermsg( cad->irc, "Account deleted" ); 232 } 233 g_free( data ); 234 } 235 236 void cmd_account_del_no( void *data ) 237 { 238 g_free( data ); 239 } 240 207 241 static void cmd_account( irc_t *irc, char **cmd ) 208 242 { … … 263 297 else 264 298 { 265 account_del( irc, a ); 266 irc_usermsg( irc, "Account deleted" ); 299 struct cmd_account_del_data *cad; 300 char *msg; 301 302 cad = g_malloc( sizeof( struct cmd_account_del_data ) ); 303 cad->a = a; 304 cad->irc = irc; 305 306 msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will " 307 "also forget all your saved nicknames. If you want " 308 "to change your username/password, use the `account " 309 "set' command. Are you sure you want to delete this " 310 "account?", a->prpl->name, a->user ); 311 query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad ); 312 g_free( msg ); 267 313 } 268 314 } … … 382 428 acc_handle = g_strdup( cmd[2] ); 383 429 430 if( !acc_handle ) 431 { 432 irc_usermsg( irc, "Not enough parameters given (need %d)", 3 ); 433 return; 434 } 435 384 436 if( ( tmp = strchr( acc_handle, '/' ) ) ) 385 437 { … … 562 614 g_free( irc->mynick ); 563 615 irc->mynick = g_strdup( cmd[2] ); 616 617 if( strcmp( cmd[0], "set_rename" ) != 0 ) 618 set_setstr( &irc->set, "root_nick", cmd[2] ); 564 619 } 565 620 else if( u->send_handler == buddy_send_handler ) … … 570 625 irc_usermsg( irc, "Nick successfully changed" ); 571 626 } 627 } 628 629 char *set_eval_root_nick( set_t *set, char *new_nick ) 630 { 631 irc_t *irc = set->data; 632 633 if( strcmp( irc->mynick, new_nick ) != 0 ) 634 { 635 char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL }; 636 637 cmd_rename( irc, cmd ); 638 } 639 640 return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL; 572 641 } 573 642 … … 774 843 else 775 844 irc_usermsg( irc, "%s is empty", set_name ); 845 846 if( strchr( set_name, '/' ) ) 847 irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); 776 848 } 777 849 else -
set.c
reb0714d r9b55485 357 357 } 358 358 359 char *set_eval_charset( set_t *set, char *value )360 {361 GIConv cd;362 363 if ( g_strncasecmp( value, "none", 4 ) == 0 )364 return value;365 366 cd = g_iconv_open( "UTF-8", value );367 if( cd == (GIConv) -1 )368 return NULL;369 370 g_iconv_close( cd );371 return value;372 }373 374 359 /* possible values: never, opportunistic, manual, always */ 375 360 char *set_eval_otr_policy( set_t *set, char *value ) -
set.h
reb0714d r9b55485 101 101 char *set_eval_halfop_buddies( set_t *set, char *value ); 102 102 char *set_eval_voice_buddies( set_t *set, char *value ); 103 char *set_eval_charset( set_t *set, char *value );104 103 char *set_eval_otr_policy( set_t *set, char *value ); 105 104 -
sock.h
reb0714d r9b55485 16 16 #else 17 17 # include <winsock2.h> 18 # ifndef _MSC_VER 19 # include <ws2tcpip.h> 20 # endif 18 # include <ws2tcpip.h> 21 19 # if !defined(BITLBEE_CORE) && defined(_MSC_VER) 22 20 # pragma comment(lib,"bitlbee.lib") 23 21 # endif 24 22 # include <io.h> 25 # define read(a,b,c) recv(a,b,c,0)26 # define write(a,b,c) send(a,b,c,0)27 # define umask _umask28 # define mode_t int29 23 # define sock_make_nonblocking(fd) { int non_block = 1; ioctlsocket(fd, FIONBIO, &non_block); } 30 24 # define sock_make_blocking(fd) { int non_block = 0; ioctlsocket(fd, FIONBIO, &non_block); } -
storage_text.c
reb0714d r9b55485 27 27 #include "bitlbee.h" 28 28 #include "crypting.h" 29 #ifdef _WIN32 30 # define umask _umask 31 # define mode_t int 32 #endif 33 34 #ifndef F_OK 35 #define F_OK 0 36 #endif 29 37 30 38 static void text_init (void) -
storage_xml.c
reb0714d r9b55485 29 29 #include "arc.h" 30 30 #include "md5.h" 31 #include <glib/gstdio.h> 32 33 #if !GLIB_CHECK_VERSION(2,8,0) 34 /* GLib < 2.8.0 doesn't have g_access, so just use the system access(). */ 35 #define g_access access 36 #endif 31 37 32 38 typedef enum … … 80 86 char *nick = xml_attr( attr_names, attr_values, "nick" ); 81 87 char *pass = xml_attr( attr_names, attr_values, "password" ); 82 md5_byte_t *pass_dec = NULL;88 int st; 83 89 84 90 if( !nick || !pass ) … … 87 93 "Missing attributes for %s element", element_name ); 88 94 } 89 else if( base64_decode( pass, &pass_dec ) != 21 ) 90 { 95 else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 ) 96 { 97 xd->pass_st = XML_PASS_WRONG; 91 98 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 92 99 "Error while decoding password attribute" ); 93 100 } 101 else if( st == 0 ) 102 { 103 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 104 xd->pass_st = XML_PASS_OK; 105 } 94 106 else 95 107 { 96 md5_byte_t pass_md5[16]; 97 md5_state_t md5_state; 98 int i; 99 100 md5_init( &md5_state ); 101 md5_append( &md5_state, (md5_byte_t*) xd->given_pass, strlen( xd->given_pass ) ); 102 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 103 md5_finish( &md5_state, pass_md5 ); 104 105 for( i = 0; i < 16; i ++ ) 106 { 107 if( pass_dec[i] != pass_md5[i] ) 108 { 109 xd->pass_st = XML_PASS_WRONG; 110 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 111 "Password mismatch" ); 112 break; 113 } 114 } 115 116 /* If we reached the end of the loop, it was a match! */ 117 if( i == 16 ) 118 { 119 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 120 xd->pass_st = XML_PASS_OK; 121 } 122 } 123 124 g_free( pass_dec ); 108 xd->pass_st = XML_PASS_WRONG; 109 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 110 "Password mismatch" ); 111 } 125 112 } 126 113 else if( xd->pass_st < XML_PASS_OK ) … … 262 249 static void xml_init( void ) 263 250 { 264 if( access( global.conf->configdir, F_OK ) != 0 )251 if( g_access( global.conf->configdir, F_OK ) != 0 ) 265 252 log_message( LOGLVL_WARNING, "The configuration directory `%s' does not exist. Configuration won't be saved.", global.conf->configdir ); 266 else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 ) 253 else if( g_access( global.conf->configdir, F_OK ) != 0 || 254 g_access( global.conf->configdir, W_OK ) != 0 ) 267 255 log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to `%s'.", global.conf->configdir ); 268 256 } … … 391 379 g_free( path2 ); 392 380 393 if( !overwrite && access( path, F_OK ) != -1)381 if( !overwrite && g_access( path, F_OK ) == 0 ) 394 382 return STORAGE_ALREADY_EXISTS; 395 383 … … 428 416 int pass_len; 429 417 430 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );418 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 ); 431 419 pass_b64 = base64_encode( pass_cr, pass_len ); 432 420 g_free( pass_cr ); … … 499 487 static storage_status_t xml_remove( const char *nick, const char *password ) 500 488 { 501 char s[512] ;489 char s[512], *lc; 502 490 storage_status_t status; 503 491 … … 506 494 return status; 507 495 508 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".xml" ); 496 lc = g_strdup( nick ); 497 nick_lc( lc ); 498 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, lc, ".xml" ); 499 g_free( lc ); 500 509 501 if( unlink( s ) == -1 ) 510 502 return STORAGE_OTHER_ERROR; -
tests/Makefile
reb0714d r9b55485 13 13 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o 14 14 15 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_crypting.o check_set.o check_jabber_sasl.o 15 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_crypting.o check_set.o check_jabber_sasl.o check_jabber_util.o 16 16 17 17 check: $(test_objs) $(addprefix ../, $(main_objs)) ../protocols/protocols.o ../lib/lib.o -
tests/check.c
reb0714d r9b55485 69 69 Suite *jabber_sasl_suite(void); 70 70 71 /* From check_jabber_sasl.c */ 72 Suite *jabber_util_suite(void); 73 71 74 int main (int argc, char **argv) 72 75 { … … 115 118 srunner_add_suite(sr, set_suite()); 116 119 srunner_add_suite(sr, jabber_sasl_suite()); 120 srunner_add_suite(sr, jabber_util_suite()); 117 121 if (no_fork) 118 122 srunner_set_fork_status(sr, CK_NOFORK); -
tests/check_arc.c
reb0714d r9b55485 7 7 #include "arc.h" 8 8 9 char *password = " TotT";9 char *password = "ArcVier"; 10 10 11 11 char *clear_tests[] = … … 14 14 "ItllBeBitlBee", 15 15 "One more boring password", 16 "Hoi hoi", 16 17 NULL 17 18 }; … … 28 29 int len; 29 30 30 len = arc_encode( clear_tests[i], 0, &crypted, password );31 len = arc_encode( clear_tests[i], 0, &crypted, password, 12 ); 31 32 len = arc_decode( crypted, len, &decrypted, password ); 32 33 … … 41 42 struct 42 43 { 43 unsigned char crypted[ 24];44 unsigned char crypted[30]; 44 45 int len; 45 46 char *decrypted; 46 47 } decrypt_tests[] = { 48 /* One block with padding. */ 47 49 { 48 50 { 49 0x c3, 0x0d, 0x43, 0xc3, 0xee, 0x80, 0xe2, 0x8c, 0x0b, 0x29, 0x32, 0x7e,50 0x 38, 0x05, 0x82, 0x10, 0x21, 0x1c, 0x4a, 0x00, 0x2c51 }, 21, "Debugging sucks"51 0x3f, 0x79, 0xb0, 0xf5, 0x91, 0x56, 0xd2, 0x1b, 0xd1, 0x4b, 0x67, 0xac, 52 0xb1, 0x31, 0xc9, 0xdb, 0xf9, 0xaa 53 }, 18, "short pass" 52 54 }, 55 56 /* Two blocks with padding. */ 53 57 { 54 58 { 55 0xb0, 0x00, 0x57, 0x0d, 0x0d, 0x0d, 0x70, 0xe1, 0xc0, 0x00, 0xa4, 0x25, 56 0x7d, 0xbe, 0x03, 0xcc, 0x24, 0xd1, 0x0c 57 }, 19, "Testing rocks" 59 0xf9, 0xa6, 0xec, 0x5d, 0xc7, 0x06, 0xb8, 0x6b, 0x63, 0x9f, 0x2d, 0xb5, 60 0x7d, 0xaa, 0x32, 0xbb, 0xd8, 0x08, 0xfd, 0x81, 0x2e, 0xca, 0xb4, 0xd7, 61 0x2f, 0x36, 0x9c, 0xac, 0xa0, 0xbc 62 }, 30, "longer password" 58 63 }, 64 65 /* This string is exactly two "blocks" long, to make sure unpadded strings also decrypt 66 properly. */ 59 67 { 60 68 { 61 0xb6, 0x92, 0x59, 0xe4, 0xf9, 0xc1, 0x7a, 0xf6, 0xf3, 0x18, 0xea, 0x28, 62 0x73, 0x6d, 0xb3, 0x0a, 0x6f, 0x0a, 0x2b, 0x43, 0x57, 0xe9, 0x3e, 0x63 63 }, 24, "OSCAR is creepy..." 69 0x95, 0x4d, 0xcf, 0x4d, 0x5e, 0x6c, 0xcf, 0xef, 0xb9, 0x80, 0x00, 0xef, 70 0x25, 0xe9, 0x17, 0xf6, 0x29, 0x6a, 0x82, 0x79, 0x1c, 0xca, 0x68, 0xb5, 71 0x4e, 0xd0, 0xc1, 0x41, 0x8e, 0xe6 72 }, 30, "OSCAR is really creepy.." 64 73 }, 65 74 { "", 0, NULL } … … 80 89 81 90 fail_if( strcmp( decrypt_tests[i].decrypted, decrypted ) != 0, 82 " %s didn't decrypt properly", clear_tests[i]);91 "`%s' didn't decrypt properly", decrypt_tests[i].decrypted ); 83 92 84 93 g_free( decrypted ); -
tests/check_irc.c
reb0714d r9b55485 37 37 irc = irc_new(g_io_channel_unix_get_fd(ch1)); 38 38 39 fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\ n"40 "USER a a a a\ r\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL);39 fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\r\n" 40 "USER a a a a\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL); 41 41 fail_unless(g_io_channel_flush(ch2, NULL) == G_IO_STATUS_NORMAL); 42 42 -
tests/check_jabber_sasl.c
reb0714d r9b55485 5 5 #include <string.h> 6 6 #include <stdio.h> 7 #include "arc.h"8 7 9 8 char *sasl_get_part( char *data, char *field ); -
unix.c
reb0714d r9b55485 42 42 static void sighandler( int signal ); 43 43 44 int main( int argc, char *argv[] , char **envp)44 int main( int argc, char *argv[] ) 45 45 { 46 46 int i = 0; … … 69 69 if( global.conf->runmode == RUNMODE_INETD ) 70 70 { 71 log_link( LOGLVL_ERROR, LOGOUTPUT_IRC ); 72 log_link( LOGLVL_WARNING, LOGOUTPUT_IRC ); 73 71 74 i = bitlbee_inetd_init(); 72 75 log_message( LOGLVL_INFO, "Bitlbee %s starting in inetd mode.", BITLBEE_VERSION ); … … 75 78 else if( global.conf->runmode == RUNMODE_DAEMON ) 76 79 { 80 log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG ); 81 log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG ); 82 77 83 i = bitlbee_daemon_init(); 78 84 log_message( LOGLVL_INFO, "Bitlbee %s starting in daemon mode.", BITLBEE_VERSION ); … … 144 150 { 145 151 char *fn = ipc_master_save_state(); 146 char **args;147 int n, i;148 152 149 153 chdir( old_cwd ); 150 154 151 n = 0; 152 args = g_new0( char *, argc + 3 ); 153 args[n++] = argv[0]; 154 if( fn ) 155 { 156 args[n++] = "-R"; 157 args[n++] = fn; 158 } 159 for( i = 1; argv[i] && i < argc; i ++ ) 160 { 161 if( strcmp( argv[i], "-R" ) == 0 ) 162 i += 2; 163 164 args[n++] = argv[i]; 165 } 155 setenv( "_BITLBEE_RESTART_STATE", fn, 1 ); 156 g_free( fn ); 166 157 167 158 close( global.listen_socket ); 168 159 169 execve( args[0], args, envp ); 160 if( execv( argv[0], argv ) == -1 ) 161 /* Apparently the execve() failed, so let's just 162 jump back into our own/current main(). */ 163 /* Need more cleanup code to make this work. */ 164 return 1; /* main( argc, argv ); */ 170 165 } 171 166 … … 228 223 return( (double) time->tv_sec + (double) time->tv_usec / 1000000 ); 229 224 } 225 226 -
welcome.txt
reb0714d r9b55485 2 2 3 3 If you've never used BitlBee before, please do read the help information using the help command. Lots of FAQs are answered there. 4 5 4 OTR users please note: Private key files are owned by the user BitlBee is running as. 5 If you already have an account on this server, just use the identify command to identify yourself.
Note: See TracChangeset
for help on using the changeset viewer.