Changeset d8d63a2
- Timestamp:
- 2006-12-05T20:40:17Z (17 years ago)
- Branches:
- master
- Children:
- 7740c4c
- Parents:
- f4aa393 (diff), 55078f5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 9 added
- 1 deleted
- 43 edited
- 21 moved
Legend:
- Unmodified
- Added
- Removed
-
Makefile
rf4aa393 rd8d63a2 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o conf.o crypting.o help.o i ni.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_text.o unix.o url.o user.o util.o12 objects = 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_OBJS) unix.o user.o 13 13 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ini.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h url.h user.h protocols/http_client.h protocols/md5.h protocols/nogaim.h protocols/proxy.h protocols/sha.h protocols/ssl_client.h 14 subdirs = protocols 14 subdirs = protocols lib 15 15 16 16 # Expansion of variables … … 43 43 44 44 distclean: clean $(subdirs) 45 rm -f Makefile.settings config.h 45 rm -f Makefile.settings config.h bitlbee.pc 46 46 find . -name 'DEADJOE' -o -name '*.orig' -o -name '*.rej' -o -name '*~' -exec rm -f {} \; 47 47 $(MAKE) -C test distclean -
account.c
rf4aa393 rd8d63a2 31 31 { 32 32 account_t *a; 33 set_t *s; 33 34 34 35 if( irc->accounts ) 35 36 { 36 37 for( a = irc->accounts; a->next; a = a->next ); 37 a = a->next = g_new0 38 a = a->next = g_new0( account_t, 1 ); 38 39 } 39 40 else … … 45 46 a->user = g_strdup( user ); 46 47 a->pass = g_strdup( pass ); 48 a->auto_connect = 1; 47 49 a->irc = irc; 48 50 51 s = set_add( &a->set, "auto_connect", "true", set_eval_account, a ); 52 s->flags |= ACC_SET_NOSAVE; 53 54 s = set_add( &a->set, "auto_reconnect", "true", set_eval_bool, a ); 55 56 s = set_add( &a->set, "password", NULL, set_eval_account, a ); 57 s->flags |= ACC_SET_NOSAVE; 58 59 s = set_add( &a->set, "username", NULL, set_eval_account, a ); 60 s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; 61 set_setstr( &a->set, "username", user ); 62 63 a->nicks = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); 64 65 /* This function adds some more settings (and might want to do more 66 things that have to be done now, although I can't think of anything. */ 67 if( prpl->acc_init ) 68 prpl->acc_init( a ); 69 49 70 return( a ); 71 } 72 73 char *set_eval_account( set_t *set, char *value ) 74 { 75 account_t *acc = set->data; 76 77 /* Double-check: We refuse to edit on-line accounts. */ 78 if( set->flags & ACC_SET_OFFLINE_ONLY && acc->gc ) 79 return NULL; 80 81 if( strcmp( set->key, "username" ) == 0 ) 82 { 83 g_free( acc->user ); 84 acc->user = g_strdup( value ); 85 return value; 86 } 87 else if( strcmp( set->key, "password" ) == 0 ) 88 { 89 g_free( acc->pass ); 90 acc->pass = g_strdup( value ); 91 return NULL; /* password shouldn't be visible in plaintext! */ 92 } 93 else if( strcmp( set->key, "server" ) == 0 ) 94 { 95 g_free( acc->server ); 96 if( *value ) 97 acc->server = g_strdup( value ); 98 else 99 acc->server = NULL; 100 return value; 101 } 102 else if( strcmp( set->key, "auto_connect" ) == 0 ) 103 { 104 if( !is_bool( value ) ) 105 return NULL; 106 107 acc->auto_connect = bool2int( value ); 108 return value; 109 } 110 111 return NULL; 50 112 } 51 113 … … 68 130 for( a = irc->accounts; a; a = a->next ) 69 131 if( a->prpl == proto && 70 a->prpl-> cmp_buddynames( handle, a->user ) == 0 )132 a->prpl->handle_cmp( handle, a->user ) == 0 ) 71 133 ret = a; 72 134 } … … 129 191 } 130 192 193 while( a->set ) 194 set_del( &a->set, a->set->key ); 195 196 g_hash_table_destroy( a->nicks ); 197 131 198 g_free( a->user ); 132 199 g_free( a->pass ); … … 142 209 void account_on( irc_t *irc, account_t *a ) 143 210 { 144 struct aim_user *u;145 146 211 if( a->gc ) 147 212 { … … 152 217 cancel_auto_reconnect( a ); 153 218 154 u = g_new0 ( struct aim_user, 1 );155 u->irc = irc;156 u->prpl = a->prpl;157 strncpy( u->username, a->user, sizeof( u->username ) - 1 );158 strncpy( u->password, a->pass, sizeof( u->password ) - 1 );159 if( a->server) strncpy( u->proto_opt[0], a->server, sizeof( u->proto_opt[0] ) - 1 );160 161 a->gc = (struct gaim_connection *) u; /* Bit hackish :-/ */162 219 a->reconnect = 0; 163 164 a->prpl->login( u ); 220 a->prpl->login( a ); 165 221 } 166 222 -
account.h
rf4aa393 rd8d63a2 34 34 char *server; 35 35 36 int auto_connect; 36 37 int reconnect; 38 39 set_t *set; 40 GHashTable *nicks; 37 41 38 42 struct irc *irc; … … 47 51 void account_off( irc_t *irc, account_t *a ); 48 52 53 char *set_eval_account( set_t *set, char *value ); 54 55 #define ACC_SET_NOSAVE 1 56 #define ACC_SET_OFFLINE_ONLY 2 57 #define ACC_SET_ONLINE_ONLY 4 58 49 59 #endif -
bitlbee.c
rf4aa393 rd8d63a2 39 39 { 40 40 #ifdef IPV6 41 struct sockaddr_in6 listen_addr; 42 #else 41 int use_ipv6 = 1; 42 struct sockaddr_in6 listen_addr6; 43 #endif 43 44 struct sockaddr_in listen_addr; 44 #endif45 45 int i; 46 46 FILE *fp; … … 49 49 log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG ); 50 50 51 global.listen_socket = socket( AF_INETx, SOCK_STREAM, 0 ); 51 #ifdef IPV6 52 if( ( global.listen_socket = socket( AF_INET6, SOCK_STREAM, 0 ) ) == -1 ) 53 { 54 use_ipv6 = 0; 55 #endif 56 global.listen_socket = socket( AF_INET, SOCK_STREAM, 0 ); 57 #ifdef IPV6 58 } 59 #endif 52 60 if( global.listen_socket == -1 ) 53 61 { … … 61 69 62 70 #ifdef IPV6 63 listen_addr.sin6_family = AF_INETx; 64 listen_addr.sin6_port = htons( global.conf->port ); 65 i = inet_pton( AF_INETx, ipv6_wrap( global.conf->iface ), &listen_addr.sin6_addr ); 66 #else 67 listen_addr.sin_family = AF_INETx; 68 listen_addr.sin_port = htons( global.conf->port ); 69 i = inet_pton( AF_INETx, global.conf->iface, &listen_addr.sin_addr ); 71 listen_addr6.sin6_family = AF_INET6; 72 listen_addr6.sin6_port = htons( global.conf->port ); 73 if( ( i = inet_pton( AF_INET6, ipv6_wrap( global.conf->iface ), &listen_addr6.sin6_addr ) ) != 1 ) 74 { 75 /* Forget about IPv6 in this function. */ 76 use_ipv6 = 0; 77 #endif 78 listen_addr.sin_family = AF_INET; 79 listen_addr.sin_port = htons( global.conf->port ); 80 if( strcmp( global.conf->iface, "::" ) == 0 ) 81 i = inet_pton( AF_INET, "0.0.0.0", &listen_addr.sin_addr ); 82 else 83 i = inet_pton( AF_INET, global.conf->iface, &listen_addr.sin_addr ); 84 #ifdef IPV6 85 } 70 86 #endif 71 87 … … 76 92 } 77 93 78 i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) ); 94 #ifdef IPV6 95 if( !use_ipv6 || ( i = bind( global.listen_socket, (struct sockaddr *) &listen_addr6, sizeof( listen_addr6 ) ) ) == -1 ) 96 #endif 97 i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) ); 79 98 if( i == -1 ) 80 99 { … … 291 310 irc_t *irc; 292 311 312 /* Since we're fork()ing here, let's make sure we won't 313 get the same random numbers as the parent/siblings. */ 314 srand( time( NULL ) ^ getpid() ); 315 293 316 /* Close the listening socket, we're a client. */ 294 317 close( global.listen_socket ); -
bitlbee.h
rf4aa393 rd8d63a2 124 124 #include "commands.h" 125 125 #include "account.h" 126 #include "nick.h" 126 127 #include "conf.h" 127 128 #include "log.h" … … 130 131 #include "query.h" 131 132 #include "sock.h" 132 #include " util.h"133 #include "misc.h" 133 134 #include "proxy.h" 134 135 -
conf.c
rf4aa393 rd8d63a2 34 34 #include "ipc.h" 35 35 36 #include "pro tocols/proxy.h"36 #include "proxy.h" 37 37 38 38 char *CONF_FILE; … … 55 55 conf->nofork = 0; 56 56 conf->verbose = 0; 57 conf->primary_storage = "text"; 57 conf->primary_storage = "xml"; 58 conf->migrate_storage = g_strsplit( "text", ",", -1 ); 58 59 conf->runmode = RUNMODE_INETD; 59 60 conf->authmode = AUTHMODE_OPEN; … … 322 323 if( g_strcasecmp( ini->section, "defaults" ) == 0 ) 323 324 { 324 set_t *s = set_find( irc, ini->key );325 set_t *s = set_find( &irc->set, ini->key ); 325 326 326 327 if( s ) -
configure
rf4aa393 rd8d63a2 32 32 33 33 events=glib 34 ldap=0 34 35 ssl=auto 35 36 36 37 arch=`uname -s` 37 38 cpu=`uname -m` 39 40 GLIB_MIN_VERSION=2.4 38 41 39 42 echo BitlBee configure … … 68 71 69 72 --ipv6=0/1 IPv6 socket support $ipv6 73 74 --ldap=0/1/auto LDAP support $ldap 70 75 71 76 --events=... Event handler (glib, libevent) $events … … 143 148 fi 144 149 145 echo CFLAGS+=-I`pwd` -I`pwd`/ protocols -I. >> Makefile.settings150 echo CFLAGS+=-I`pwd` -I`pwd`/lib -I`pwd`/protocols -I. >> Makefile.settings 146 151 147 152 echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings 148 153 149 154 if [ -n "$CC" ]; then 150 echo "CC=$CC" >> Makefile.settings;155 CC=$CC 151 156 elif type gcc > /dev/null 2> /dev/null; then 152 echo "CC=gcc" >> Makefile.settings;157 CC=gcc 153 158 elif type cc > /dev/null 2> /dev/null; then 154 echo "CC=cc" >> Makefile.settings;159 CC=cc 155 160 else 156 161 echo 'Cannot find a C compiler, aborting.' 157 162 exit 1; 158 163 fi 164 165 echo "CC=$CC" >> Makefile.settings; 159 166 160 167 if [ -n "$LD" ]; then … … 172 179 173 180 if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG glib-2.0; then 174 cat<<EOF>>Makefile.settings 181 if $PKG_CONFIG glib-2.0 --atleast-version=$GLIB_MIN_VERSION; then 182 cat<<EOF>>Makefile.settings 175 183 EFLAGS+=`$PKG_CONFIG --libs glib-2.0 gmodule-2.0` 176 184 CFLAGS+=`$PKG_CONFIG --cflags glib-2.0 gmodule-2.0` 177 185 EOF 178 else 186 else 187 echo 188 echo 'Found glib2 '`$PKG_CONFIG glib-2.0 --modversion`', but version '$GLIB_MIN_VERSION' or newer is required.' 189 exit 1 190 fi 191 else 192 echo 179 193 echo 'Cannot find glib2 development libraries, aborting. (Install libglib2-dev?)' 180 exit 1 ;194 exit 1 181 195 fi 182 196 … … 234 248 } 235 249 236 if [ "$msn" = 1 -o "$jabber" = 1 ]; then 237 if [ "$ssl" = "auto" ]; then 238 detect_gnutls 239 if [ "$ret" = "0" ]; then 240 detect_nss 241 fi; 242 elif [ "$ssl" = "gnutls" ]; then 243 detect_gnutls; 244 elif [ "$ssl" = "nss" ]; then 245 detect_nss; 246 elif [ "$ssl" = "openssl" ]; then 250 detect_ldap() 251 { 252 TMPFILE=`mktemp` 253 if $CC -o $TMPFILE -shared -lldap 2>/dev/null >/dev/null; then 254 cat<<EOF>>Makefile.settings 255 EFLAGS+=-lldap 256 CFLAGS+= 257 EOF 258 ldap=1 259 rm -f $TMPFILE 260 ret=1 261 else 262 ldap=0 263 ret=0 264 fi 265 } 266 267 if [ "$ssl" = "auto" ]; then 268 detect_gnutls 269 if [ "$ret" = "0" ]; then 270 detect_nss 271 fi 272 elif [ "$ssl" = "gnutls" ]; then 273 detect_gnutls 274 elif [ "$ssl" = "nss" ]; then 275 detect_nss 276 elif [ "$ssl" = "openssl" ]; then 277 echo 278 echo 'No detection code exists for OpenSSL. Make sure that you have a complete' 279 echo 'install of OpenSSL (including devel/header files) before reporting' 280 echo 'compilation problems.' 281 echo 282 echo 'Also, keep in mind that the OpenSSL is, according to some people, not' 283 echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better' 284 echo 'supported by us. However, on many BSD machines, OpenSSL can be considered' 285 echo 'part of the operating system, which makes it GPL-compatible.' 286 echo 287 echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2' 288 echo ' http://www.gnome.org/~markmc/openssl-and-the-gpl.html' 289 echo 290 echo 'Please note that distributing a BitlBee binary which links to OpenSSL is' 291 echo 'probably illegal. If you want to create and distribute a binary BitlBee' 292 echo 'package, you really should use GnuTLS or NSS instead.' 293 echo 294 echo 'Also, the OpenSSL license requires us to say this:' 295 echo ' * "This product includes software developed by the OpenSSL Project' 296 echo ' * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"' 297 298 echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings 299 300 ret=1 301 elif [ "$ssl" = "bogus" ]; then 302 echo 303 echo 'Using bogus SSL code. This means some features will not work properly.' 304 305 ## Yes, you, at the console! How can you authenticate if you don't have any SSL!? 306 if [ "$msn" = "1" ]; then 247 307 echo 248 echo 'No detection code exists for OpenSSL. Make sure that you have a complete' 249 echo 'install of OpenSSL (including devel/header files) before reporting' 250 echo 'compilation problems.' 251 echo 252 echo 'Also, keep in mind that the OpenSSL is, according to some people, not' 253 echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better' 254 echo 'supported by us. However, on many BSD machines, OpenSSL can be considered' 255 echo 'part of the operating system, which makes it GPL-compatible.' 256 echo 257 echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2' 258 echo ' http://www.gnome.org/~markmc/openssl-and-the-gpl.html' 259 echo 260 echo 'Please note that distributing a BitlBee binary which links to OpenSSL is' 261 echo 'probably illegal. If you want to create and distribute a binary BitlBee' 262 echo 'package, you really should use GnuTLS or NSS instead.' 263 echo 264 echo 'Also, the OpenSSL license requires us to say this:' 265 echo ' * "This product includes software developed by the OpenSSL Project' 266 echo ' * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"' 267 268 echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings 269 270 ret=1; 271 elif [ "$ssl" = "bogus" ]; then 272 echo 273 echo 'Using bogus SSL code. This will not make the MSN module work, but it will' 274 echo 'allow you to use the Jabber module - although without working SSL support.' 275 276 ret=1; 277 else 278 echo 279 echo 'ERROR: Unknown SSL library specified.' 280 exit 1; 281 fi 282 283 if [ "$ret" = "0" ]; then 284 echo 285 echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).' 286 echo ' This is necessary for MSN and full Jabber support. To continue,' 287 echo ' install a suitable SSL library or disable MSN support (--msn=0).' 288 echo ' If you want Jabber without SSL support you can try --ssl=bogus.' 289 290 exit 1; 291 fi; 292 293 echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings 294 fi 308 echo 'Real SSL support is necessary for MSN authentication, will build without' 309 echo 'MSN protocol support.' 310 msn=0 311 fi 312 313 ret=1 314 else 315 echo 316 echo 'ERROR: Unknown SSL library specified.' 317 exit 1 318 fi 319 320 if [ "$ret" = "0" ]; then 321 echo 322 echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).' 323 echo ' Please note that this script doesn'\''t have detection code for OpenSSL,' 324 echo ' so if you want to use that, you have to select it by hand. If you don'\''t' 325 echo ' need SSL support, you can select the "bogus" SSL library. (--ssl=bogus)' 326 327 exit 1 328 fi; 329 330 echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings 331 332 STORAGES="text xml" 333 334 if [ "$ldap" = "auto" ]; then 335 detect_ldap 336 fi 337 338 if [ "$ldap" = 0 ]; then 339 echo "#undef WITH_LDAP" >> config.h 340 elif [ "$ldap" = 1 ]; then 341 echo "#define WITH_LDAP 1" >> config.h 342 STORAGES="$STORAGES ldap" 343 fi 344 345 for i in $STORAGES; do 346 STORAGE_OBJS="$STORAGE_OBJS storage_$i.o" 347 done 348 echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings 295 349 296 350 if [ "$strip" = 0 ]; then … … 306 360 elif type strip > /dev/null 2> /dev/null; then 307 361 echo "STRIP=strip" >> Makefile.settings; 308 elif /bin/test -x /usr/ccs/bin/strip; then309 echo "STRIP=/usr/ccs/bin/strip" >> Makefile.settings;310 362 else 311 363 echo … … 391 443 if [ "$protocols" = "PROTOCOLS = " ]; then 392 444 echo "WARNING: You haven't selected any communication protocol to compile!" 393 echo " Bitl bee will run, but you will be unable to connect to IM servers!"445 echo " BitlBee will run, but you will be unable to connect to IM servers!" 394 446 fi 395 447 … … 426 478 427 479 if [ "$debug" = "1" ]; then 428 echo ' Debugging enabled.' ;429 else 430 echo ' Debugging disabled.' ;480 echo ' Debugging enabled.' 481 else 482 echo ' Debugging disabled.' 431 483 fi 432 484 433 485 if [ "$strip" = "1" ]; then 434 echo ' Binary stripping enabled.'; 435 else 436 echo ' Binary stripping disabled.'; 437 fi 438 439 echo ' Using event handler: '$events; 440 echo ' Using SSL library: '$ssl; 441 442 #if [ "$flood" = "0" ]; then 443 # echo ' Flood protection disabled.'; 444 #else 445 # echo ' Flood protection enabled.'; 446 #fi 486 echo ' Binary stripping enabled.' 487 else 488 echo ' Binary stripping disabled.' 489 fi 490 491 echo ' Using event handler: '$events 492 echo ' Using SSL library: '$ssl 493 echo ' Building with these storage backends: '$STORAGES 447 494 448 495 if [ -n "$protocols" ]; then 449 echo ' Building with these protocols:' $protocols ;450 else 451 echo ' Building without IM-protocol support. We wish you a lot of fun...' ;452 fi 496 echo ' Building with these protocols:' $protocols 497 else 498 echo ' Building without IM-protocol support. We wish you a lot of fun...' 499 fi -
doc/CHANGES
rf4aa393 rd8d63a2 1 Version x.x: 2 - Added ForkDaemon mode next to the existing Daemon- and inetd modes. With 3 ForkDaemon you can run BitlBee as a stand-alone daemon and every connection 4 will run in its own process. No more need to configure inetd, and still you 5 don't get the stability problems BitlBee unfortunately still has in ordinary 6 (one-process) daemon mode. 7 - Added inter-process/connection communication. This made it possible to 8 implement some IRC operator features like WALLOPs, KILL, DIE, REHASH and 9 more. 10 - Added hooks for using libevent instead of GLib for event handling. This 11 should improve scalability, although this won't really be useful yet because 12 the one-process daemon mode is not reliable enough. 13 - BitlBee now makes the buddy quits when doing "account off" look like a 14 netsplit. Modern IRC clients show this in a different, more compact way. 15 - GLib 1.x compatibility was dropped. BitlBee now requires GLib 2.4 or newer. 16 This allows us to use more GLib features (like the XML parser). By now GLib 17 1.x is so old that supporting it really isn't necessary anymore. 18 - Many, many, MANY little changes, improvements, fixes. Using non-blocking 19 I/O as much as possible, fixed lots of little bugs (including bugs that 20 affected daemon mode stability). See the bzr logs for more information. 21 - Most important change: New file format for user data (accounts, nicks and 22 settings). Migration to the new format should happen transparently, 23 BitlBee will read the old files and once you quit/save it will save in the 24 new format. It is recommended to delete the old files (BitlBee doesn't do 25 this automatically, it will just ignore them) since they won't be used 26 anymore (and since the old file format is a security risk). Some advantages 27 of this file format switch: 28 * Safer format, since the identify-password is now salted before generating 29 a checksum. This way one can't use MD5 reverse lookup databases to crack 30 passwords. Also, the IM-account passwords are encrypted using RC4 instead 31 of the simple obfuscation scheme which BitlBee used so far. 32 * Easier to extend than the previous format (at least the .nicks format was 33 horribly limited). 34 * Nicknames for buddies are now saved per-account instead of per-protocol. 35 So far having one buddy on multiple accounts of the same protocol was a 36 problem because the nicks generated for the two "instances" of this buddy 37 were very unpredictable. 38 NOTE: This also means that "account del" removes not just the account, 39 BUT ALSO ALL NICKNAMES! If you're changing IM accounts and don't want to 40 lose the nicknames, you can now use "account set" to change the username 41 and password for the existing connection. 42 * Per-account settings (see the new "account set" command). 43 44 Version 1.0.3: 45 - Fixed ugliness in block/allow list commands (still not perfect though, the 46 list is empty or not up-to-date for most protocols). 47 - OSCAR module doesn't send the ICQ web-aware flag anymore, which seems to 48 get rid of a lot of ICQ spam. 49 - added show_got_added(), BitlBee asks you, after authorizing someone, if you 50 want to add him/her to your list too. 51 - add -tmp, mainly convenient if you want to talk to people who are not in 52 your list. 53 - Fixed ISON command, should work better with irssi now. 54 - Fixed compilation with tcc. 55 - Fixed xinetd-file. 56 - Misc. (crash)bug fixes, including one in the root command parsing that 57 caused mysterious error messages sometimes. 58 59 Finished 24 Jun 2006 (Happy 4th birthday, BitlBee!) 60 61 Version 1.0.2: 62 - Pieces of code cleanup, fixes for possible problems in error checking. 63 - Fixed an auto-reconnect cleanup problem that caused crashes in daemon mode. 64 - /AWAY in daemon mode now doesn't set the away state for every connection 65 anymore. 66 - Fixed a crash-bug on empty help subjects. 67 - Jabber now correctly sets the current away state when connecting. 68 - Added Invisible and Hidden to the away state alias list, invisible mode 69 should be pretty usable now. 70 - Fixed handling of iconv(): It's now done for everything that goes between 71 BitlBee and the IRC client, instead of doing it (almost) every time 72 something goes to or come from the IM-modules. Should've thought about 73 that before. :-) 74 - When cleaning up MSN switchboards with unsent msgs, it now also says which 75 contact those messages were meant for. 76 - You can now use the block and allow commands to see your current block/ 77 allow list. 78 79 Finished 1 Apr 2006 80 81 Version 1.0.1: 82 - Support for AIM groupchats. 83 - Improved typing notification support for at least AIM. 84 - BitlBee sends a 005 reply when logging in, this informs modern IRC clients 85 of some of BitlBee's capabilities. This might also solve problems some 86 people were having with the new control channel name. 87 - MSN switchboards are now properly reset when talking to a person who is 88 offline. This fixes problems with messages to MSN people that sometimes 89 didn't arrive. 90 - Fixed one of the problems that made BitlBee show online Jabber people as 91 offline. 92 - Fixed problems with commas in MSN passwords. 93 - Added some consts for read-only data, which should make the BitlBee per- 94 process memory footprint a bit smaller. 95 - Other bits of code cleanup. 96 97 Finished 14 Jan 2006 98 1 99 Version 1.0: 2 100 - Removed some crashy debugging code. -
doc/README
rf4aa393 rd8d63a2 155 155 ==================== 156 156 157 BitlBee stores the accounts and settings (not your contact list though) in 158 some sort of encrypted/obfuscated format. 159 160 *** THIS IS NOT A SAFE FORMAT! *** 161 162 You should still make sure the rights to the configuration directory and 163 files are set so that only root and the BitlBee user can read/write them. 164 165 This format is not to prevent malicicous users from running with your 166 passwords, but to prevent accidental glimpses of the administrators to cause 167 any harm. You have no choice but to trust root though. 157 There used to be a note here about the simple obfuscation method used to 158 make the passwords in the configuration files unreadable. However, BitlBee 159 now uses a better format (and real encryption (salted MD5 and RC4)) to store 160 the passwords. This means that people who somehow get their hands on your 161 configuration files can't easily extract your passwords from them anymore. 162 163 However, once you log into the BitlBee server and send your password, an 164 intruder with tcpdump can still read your passwords. This can't really be 165 avoided, of course. The new format is a lot more reliable (because it can't 166 be cracked with just very basic crypto analysis anymore), but you still have 167 to be careful. The main extra protection offered by the new format is that 168 the files can only be cracked with some help from the user (by sending the 169 password at login time). 170 171 So if you run a public server, it's most important that you don't give root 172 access to people who like to play with tcpdump. Also, it's a good idea to 173 delete all *.nicks/*.accounts files as soon as BitlBee converted them to the 174 new format (which happens as soon as the user logs in, it can't be done 175 automatically because it needs the password for that account). You won't 176 need them anymore (unless you want to switch back to an older BitlBee 177 version) and they only make it easier for others to crack your passwords. 168 178 169 179 … … 192 202 BitlBee - An IRC to other chat networks gateway 193 203 <http://www.bitlbee.org/> 194 Copyright (C) 2002-200 5Wilmer van der Gaast <wilmer@gaast.net>204 Copyright (C) 2002-2006 Wilmer van der Gaast <wilmer@gaast.net> 195 205 and others -
doc/user-guide/Makefile
rf4aa393 rd8d63a2 28 28 xsltproc --xinclude --output $@ docbook.xsl $< 29 29 30 help.txt: help.xml help.xsl 30 help.txt: help.xml help.xsl commands.xml misc.xml quickstart.xml 31 31 xsltproc --stringparam extraparanewline "$(EXTRAPARANEWLINE)" --xinclude help.xsl $< | perl -0077 -pe 's/\n\n%/\n%/s; s/_b_/\002/g;' > $@ 32 32 -
doc/user-guide/commands.xml
rf4aa393 rd8d63a2 11 11 12 12 <para> 13 Available actions: add, del, list, on, off . See <emphasis>help account <action></emphasis> for more information.13 Available actions: add, del, list, on, off and set. See <emphasis>help account <action></emphasis> for more information. 14 14 </para> 15 15 … … 26 26 27 27 <bitlbee-command name="jabber"> 28 <syntax>account add jabber <handle > <password> [<servertag>]</syntax>28 <syntax>account add jabber <handle@server.tld> <password> [<servertag>]</syntax> 29 29 30 30 <description> 31 31 <para> 32 Note that the servertag argument is optional. You only have to use it if the part after the @ in your handle isn't the hostname of your Jabber server, or if you want to use SSL/connect to a non-standard port number. The format is simple: [<servername>[:<portnumber>][:ssl]]. For example, this is how you can connect to Google Talk: 32 Note that the servertag argument is optional. You only have to use it if the part after the @ in your handle isn't the hostname of your Jabber server, or if you want to use SSL/connect to a non-standard port number. The format is simple: [<servername>[:<portnumber>][:ssl]]. 33 </para> 34 </description> 35 36 <description> 37 <para> 38 Google Talk uses the Jabber protocol. Please note that Google talk is SSL-only, but officially reachable over both port 5222 and 5223. Usually BitlBee users have to connect via port 5223, for example like this: 33 39 </para> 34 40 </description> … … 38 44 <ircline nick="root">Account successfully added</ircline> 39 45 </ircexample> 40 41 <description>42 <para>43 Note that Google talk is SSL-only, but officially reachable over both port 5222 and 5223. However, for some people only port 5222 works, for some people only 5223. This is something you'll have to try out.44 </para>45 </description>46 46 </bitlbee-command> 47 47 48 48 <bitlbee-command name="msn"> 49 <syntax>account add msn <handle > <password></syntax>49 <syntax>account add msn <handle@server.tld> <password></syntax> 50 50 51 51 <description> … … 103 103 <description> 104 104 <para> 105 This command will try to log into the specified account. If no account is specified, BitlBee will log into all the accounts . (Including accounts awaiting a reconnection)105 This command will try to log into the specified account. If no account is specified, BitlBee will log into all the accounts that have the auto_connect flag set. 106 106 </para> 107 107 … … 118 118 <description> 119 119 <para> 120 This command disconnects the connection for the specified account. If no account is specified, BitlBee will deactivate all active accounts . (Including accounts awaiting a reconnection)120 This command disconnects the connection for the specified account. If no account is specified, BitlBee will deactivate all active accounts and cancel all pending reconnects. 121 121 </para> 122 122 … … 133 133 <para> 134 134 This command gives you a list of all the accounts known by BitlBee, including the numbers you'll need for most account commands. 135 </para> 136 </description> 137 </bitlbee-command> 138 139 <bitlbee-command name="set"> 140 <syntax>account set <account id></syntax> 141 <syntax>account set <account id>/<setting></syntax> 142 <syntax>account set <account id>/<setting> <value></syntax> 143 144 <description> 145 <para> 146 This account can be used to change various settings for IM accounts. For all protocols, this command can be used to change the handle or the password BitlBee uses to log in and if it should be logged in automatically. Some protocols have additional settings. You can see the settings available for a connection by typing <emphasis>account set <account id></emphasis>. 147 </para> 148 149 <para> 150 For more infomation about a setting, see <emphasis>help set <setting></emphasis>. 151 </para> 152 153 <para> 154 The account ID can be a number (see <emphasis>account list</emphasis>), the protocol name or (part of) the screenname, as long as it matches only one connection. 135 155 </para> 136 156 </description> … … 276 296 </bitlbee-command> 277 297 278 <bitlbee-setting name="charset" type="string"> 298 <bitlbee-setting name="auto_connect" type="boolean" scope="both"> 299 <default>true</default> 300 301 <description> 302 <para> 303 With this option enabled, when you identify BitlBee will automatically connect to your accounts, with this disabled it will not do this. 304 </para> 305 306 <para> 307 This setting can also be changed for specific accounts using the <emphasis>account set</emphasis> command. (However, these values will be ignored if the global <emphasis>auto_connect</emphasis> setting is disabled!) 308 </para> 309 </description> 310 </bitlbee-setting> 311 312 <bitlbee-setting name="auto_reconnect" type="boolean" scope="both"> 313 <default>false</default> 314 315 <description> 316 <para> 317 If an IM-connections breaks, you're supposed to bring it back up yourself. Having BitlBee do this automatically might not always be a good idea, for several reasons. If you want the connections to be restored automatically, you can enable this setting. 318 </para> 319 320 <para> 321 See also the <emphasis>auto_reconnect_delay</emphasis> setting. 322 </para> 323 324 <para> 325 This setting can also be changed for specific accounts using the <emphasis>account set</emphasis> command. (However, these values will be ignored if the global <emphasis>auto_reconnect</emphasis> setting is disabled!) 326 </para> 327 </description> 328 </bitlbee-setting> 329 330 <bitlbee-setting name="auto_reconnect_delay" type="integer" scope="global"> 331 <default>300</default> 332 333 <description> 334 <para> 335 Tell BitlBee after how many seconds it should attempt to bring an IM-connection back up after a crash. It's not a good idea to set this value very low, it will cause too much useless traffic when an IM-server is down for a few hours. 336 </para> 337 338 <para> 339 See also the <emphasis>auto_reconnect</emphasis> setting. 340 </para> 341 </description> 342 </bitlbee-setting> 343 344 <bitlbee-setting name="away_devoice" type="boolean" scope="global"> 345 <default>true</default> 346 347 <description> 348 <para> 349 With this option enabled, the root user devoices people when they go away (just away, not offline) and gives the voice back when they come back. You might dislike the voice-floods you'll get if your contact list is huge, so this option can be disabled. 350 </para> 351 </description> 352 </bitlbee-setting> 353 354 <bitlbee-setting name="buddy_sendbuffer" type="boolean" scope="global"> 355 <default>false</default> 356 357 <description> 358 <para> 359 By default, when you send a message to someone, BitlBee forwards this message to the user immediately. When you paste a large number of lines, the lines will be sent in separate messages, which might not be very nice to read. If you enable this setting, BitlBee will buffer your messages and wait for more data. 360 </para> 361 362 <para> 363 Using the <emphasis>buddy_sendbuffer_delay</emphasis> setting you can specify the number of seconds BitlBee should wait for more data before the complete message is sent. 364 </para> 365 366 <para> 367 Please note that if you remove a buddy from your list (or if the connection to that user drops) and there's still data in the buffer, this data will be lost. BitlBee will not try to send the message to the user in those cases. 368 </para> 369 </description> 370 </bitlbee-setting> 371 372 <bitlbee-setting name="buddy_sendbuffer_delay" type="integer" scope="global"> 373 <default>200</default> 374 375 <description> 376 377 <para> 378 Tell BitlBee after how many (mili)seconds a buffered message should be sent. Values greater than 5 will be interpreted as miliseconds, 5 and lower as seconds. 379 </para> 380 381 <para> 382 See also the <emphasis>buddy_sendbuffer</emphasis> setting. 383 </para> 384 </description> 385 </bitlbee-setting> 386 387 <bitlbee-setting name="charset" type="string" scope="global"> 279 388 <default>iso8859-1</default> 280 389 <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values> … … 292 401 </bitlbee-setting> 293 402 294 <bitlbee-setting name="private" type="boolean"> 295 <default>True</default> 296 297 <description> 298 299 <para> 300 If value is true, messages from users will appear in separate query windows. If false, messages from users will appear in the control channel. 301 </para> 302 303 <para> 304 This setting is remembered (during one session) per-user, this setting only changes the default state. This option takes effect as soon as you reconnect. 305 </para> 306 </description> 307 </bitlbee-setting> 308 309 <bitlbee-setting name="save_on_quit" type="boolean"> 310 <default>True</default> 311 312 <description> 313 <para> 314 If enabled causes BitlBee to save all current settings and account details when user disconnects. This is enabled by default, and these days there's not really a reason to have it disabled anymore. 315 </para> 316 </description> 317 </bitlbee-setting> 318 319 <bitlbee-setting name="strip_html" type="boolean"> 320 <default>True</default> 321 322 <description> 323 <para> 324 Determines what BitlBee should do with HTML in messages. Normally this is turned on and HTML will be stripped from messages, if BitlBee thinks there is HTML. 325 </para> 326 <para> 327 If BitlBee fails to detect this sometimes (most likely in AIM messages over an ICQ connection), you can set this setting to <emphasis>always</emphasis>, but this might sometimes accidentally strip non-HTML things too. 328 </para> 329 </description> 330 </bitlbee-setting> 331 332 <bitlbee-setting name="debug" type="boolean"> 333 <default>False</default> 403 <bitlbee-setting name="debug" type="boolean" scope="global"> 404 <default>false</default> 334 405 335 406 <description> … … 340 411 </bitlbee-setting> 341 412 342 <bitlbee-setting name="to_char" type="string"> 343 <default>": "</default> 344 345 <description> 346 347 <para> 348 It's customary that messages meant for one specific person on an IRC channel are prepended by his/her alias followed by a colon ':'. BitlBee does this by default. If you prefer a different character, you can set it using <emphasis>set to_char</emphasis>. 349 </para> 350 351 <para> 352 Please note that this setting is only used for incoming messages. For outgoing messages you can use ':' (colon) or ',' to separate the destination nick from the message, and this is not configurable. 353 </para> 354 </description> 355 </bitlbee-setting> 356 357 <bitlbee-setting name="typing_notice" type="boolean"> 358 <default>False</default> 359 360 <description> 361 <para> 362 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. ;-) 363 </para> 364 </description> 365 </bitlbee-setting> 366 367 <bitlbee-setting name="ops" type="string"> 368 <default>both</default> 369 <possible-values>both, root, user, none</possible-values> 370 371 <description> 372 <para> 373 Some people prefer themself and root to have operator status in &bitlbee, other people don't. You can change these states using this setting. 374 </para> 375 376 <para> 377 The value "both" means both user and root get ops. "root" means, well, just root. "user" means just the user. "none" means nobody will get operator status. 378 </para> 379 </description> 380 </bitlbee-setting> 381 382 <bitlbee-setting name="away_devoice" type="boolean"> 383 <default>True</default> 384 385 <description> 386 <para> 387 With this option enabled, the root user devoices people when they go away (just away, not offline) and gives the voice back when they come back. You might dislike the voice-floods you'll get if your contact list is huge, so this option can be disabled. 388 </para> 389 </description> 390 </bitlbee-setting> 391 392 <bitlbee-setting name="handle_unknown" type="string"> 413 <bitlbee-setting name="default_target" type="string" scope="global"> 414 <default>root</default> 415 <possible-values>root, last</possible-values> 416 417 <description> 418 <para> 419 With this value set to <emphasis>root</emphasis>, lines written in the control channel without any nickname in front of them will be interpreted as commands. If you want BitlBee to send those lines to the last person you addressed in the control channel, set this to <emphasis>last</emphasis>. 420 </para> 421 </description> 422 </bitlbee-setting> 423 424 <bitlbee-setting name="display_name" type="string" scope="account"> 425 <description> 426 <para> 427 Currently only available for MSN connections. This setting allows you to read and change your "friendly name" for this connection. Since this is a server-side setting, it can't be changed when the account is off-line. 428 </para> 429 </description> 430 </bitlbee-setting> 431 432 <bitlbee-setting name="display_namechanges" type="boolean" scope="global"> 433 <default>false</default> 434 435 <description> 436 <para> 437 With this option enabled, root will inform you when someone in your buddy list changes his/her "friendly name". 438 </para> 439 </description> 440 </bitlbee-setting> 441 442 <bitlbee-setting name="handle_unknown" type="string" scope="global"> 393 443 <default>root</default> 394 444 <possible-values>root, add, add_private, add_channel, ignore</possible-values> … … 417 467 </bitlbee-setting> 418 468 419 <bitlbee-setting name="auto_connect" type="boolean"> 420 <default>True</default> 421 422 <description> 423 <para> 424 With this option enabled, when you identify BitlBee will automatically connect to your accounts, with this disabled it will not do this. 425 </para> 426 </description> 427 </bitlbee-setting> 428 429 <bitlbee-setting name="auto_reconnect" type="boolean"> 430 <default>False</default> 431 432 <description> 433 <para> 434 If an IM-connections breaks, you're supposed to bring it back up yourself. Having BitlBee do this automatically might not always be a good idea, for several reasons. If you want the connections to be restored automatically, you can enable this setting. 435 </para> 436 437 <para> 438 See also the <emphasis>auto_reconnect_delay</emphasis> setting. 439 </para> 440 </description> 441 442 </bitlbee-setting> 443 444 <bitlbee-setting name="auto_reconnect_delay" type="integer"> 445 <default>300</default> 446 447 <description> 448 449 <para> 450 Tell BitlBee after how many seconds it should attempt to bring an IM-connection back up after a crash. It's not a good idea to set this value very low, it will cause too much useless traffic when an IM-server is down for a few hours. 451 </para> 452 453 <para> 454 See also the <emphasis>auto_reconnect</emphasis> setting. 455 </para> 456 </description> 457 </bitlbee-setting> 458 459 <bitlbee-setting name="buddy_sendbuffer" type="boolean"> 460 <default>False</default> 461 462 <description> 463 464 <para> 465 By default, when you send a message to someone, BitlBee forwards this message to the user immediately. When you paste a large number of lines, the lines will be sent in separate messages, which might not be very nice to read. If you enable this setting, BitlBee will buffer your messages and wait for more data. 466 </para> 467 468 <para> 469 Using the <emphasis>buddy_sendbuffer_delay</emphasis> setting you can specify the number of seconds BitlBee should wait for more data before the complete message is sent. 470 </para> 471 472 <para> 473 Please note that if you remove a buddy from your list (or if the connection to that user drops) and there's still data in the buffer, this data will be lost. BitlBee will not try to send the message to the user in those cases. 474 </para> 475 </description> 476 477 </bitlbee-setting> 478 479 <bitlbee-setting name="buddy_sendbuffer_delay" type="integer"> 480 <default>200</default> 481 482 <description> 483 484 <para> 485 Tell BitlBee after how many (mili)seconds a buffered message should be sent. Values greater than 5 will be interpreted as miliseconds, 5 and lower as seconds. 486 </para> 487 488 <para> 489 See also the <emphasis>buddy_sendbuffer</emphasis> setting. 490 </para> 491 </description> 492 493 </bitlbee-setting> 494 495 <bitlbee-setting name="default_target" type="string"> 496 <default>root</default> 497 <possible-values>root, last</possible-values> 498 499 <description> 500 <para> 501 With this value set to <emphasis>root</emphasis>, lines written in the control channel without any nickname in front of them will be interpreted as commands. If you want BitlBee to send those lines to the last person you addressed in the control channel, set this to <emphasis>last</emphasis>. 502 </para> 503 </description> 504 505 </bitlbee-setting> 506 507 <bitlbee-setting name="display_namechanges" type="boolean"> 508 <default>False</default> 509 510 <para> 511 With this option enabled, root will inform you when someone in your buddy list changes his/her "friendly name". 512 </para> 513 </bitlbee-setting> 514 515 <bitlbee-setting name="password" type="string"> 516 <description> 517 <para> 518 Use this setting to change your "NickServ" password. 519 </para> 520 </description> 521 </bitlbee-setting> 522 523 <bitlbee-setting name="query_order" type="string"> 469 <bitlbee-setting name="lcnicks" type="boolean" scope="global"> 470 <default>true</default> 471 472 <description> 473 <para> 474 Hereby you can change whether you want all lower case nick names or leave the case as it intended by your peer. 475 </para> 476 </description> 477 478 </bitlbee-setting> 479 480 <bitlbee-setting name="ops" type="string" scope="global"> 481 <default>both</default> 482 <possible-values>both, root, user, none</possible-values> 483 484 <description> 485 <para> 486 Some people prefer themself and root to have operator status in &bitlbee, other people don't. You can change these states using this setting. 487 </para> 488 489 <para> 490 The value "both" means both user and root get ops. "root" means, well, just root. "user" means just the user. "none" means nobody will get operator status. 491 </para> 492 </description> 493 </bitlbee-setting> 494 495 <bitlbee-setting name="password" type="string" scope="both"> 496 <description> 497 <para> 498 Use this global setting to change your "NickServ" password. 499 </para> 500 501 <para> 502 This setting is also available for all IM accounts to change the password BitlBee uses to connect to the service. 503 </para> 504 505 <para> 506 Note that BitlBee will always say this setting is empty. This doesn't mean there is no password, it just means that, for security reasons, BitlBee stores passwords somewhere else so they can't just be retrieved in plain text. 507 </para> 508 </description> 509 </bitlbee-setting> 510 511 <bitlbee-setting name="port" type="integer" scope="account"> 512 <description> 513 <para> 514 Currently only available for Jabber connections. Specifies the port number to connect to. Usually this should be set to 5222, or 5223 for SSL-connections. 515 </para> 516 </description> 517 </bitlbee-setting> 518 519 <bitlbee-setting name="private" type="boolean" scope="global"> 520 <default>true</default> 521 522 <description> 523 <para> 524 If value is true, messages from users will appear in separate query windows. If false, messages from users will appear in the control channel. 525 </para> 526 527 <para> 528 This setting is remembered (during one session) per-user, this setting only changes the default state. This option takes effect as soon as you reconnect. 529 </para> 530 </description> 531 </bitlbee-setting> 532 533 <bitlbee-setting name="query_order" type="string" scope="global"> 524 534 <default>lifo</default> 525 535 <possible-values>lifo, fifo</possible-values> … … 536 546 </bitlbee-setting> 537 547 538 <bitlbee-setting name="lcnicks" type="boolean"> 539 <default>True</default> 540 541 <description> 542 <para> 543 Hereby you can change whether you want all lower case nick names or leave the case as it intended by your peer. 544 </para> 545 </description> 546 548 <bitlbee-setting name="resource" type="string" scope="account"> 549 <default>BitlBee</default> 550 551 <description> 552 <para> 553 Can be set for Jabber connections. You can use this to connect to your Jabber account from multiple clients at once, with every client using a different resource string. 554 </para> 555 </description> 556 </bitlbee-setting> 557 558 <bitlbee-setting name="save_on_quit" type="boolean" scope="global"> 559 <default>true</default> 560 561 <description> 562 <para> 563 If enabled causes BitlBee to save all current settings and account details when user disconnects. This is enabled by default, and these days there's not really a reason to have it disabled anymore. 564 </para> 565 </description> 566 </bitlbee-setting> 567 568 <bitlbee-setting name="server" type="string" scope="account"> 569 <description> 570 <para> 571 Can be set for Jabber- and OSCAR-connections. For OSCAR, this must be set to <emphasis>login.icq.com</emphasis> if it's an ICQ connection, or <emphasis>login.oscar.aol.com</emphasis> if it's an AIM connection. For Jabber, you have to set this if the servername isn't equal to the part after the @ in the Jabber handle. 572 </para> 573 </description> 574 </bitlbee-setting> 575 576 <bitlbee-setting name="ssl" type="boolean" scope="account"> 577 <default>false</default> 578 579 <description> 580 <para> 581 Currently only available for Jabber connections. Set this to true if the server accepts SSL connections. 582 </para> 583 </description> 584 </bitlbee-setting> 585 586 <bitlbee-setting name="strip_html" type="boolean" scope="global"> 587 <default>true</default> 588 589 <description> 590 <para> 591 Determines what BitlBee should do with HTML in messages. Normally this is turned on and HTML will be stripped from messages, if BitlBee thinks there is HTML. 592 </para> 593 <para> 594 If BitlBee fails to detect this sometimes (most likely in AIM messages over an ICQ connection), you can set this setting to <emphasis>always</emphasis>, but this might sometimes accidentally strip non-HTML things too. 595 </para> 596 </description> 597 </bitlbee-setting> 598 599 <bitlbee-setting name="to_char" type="string" scope="global"> 600 <default>": "</default> 601 602 <description> 603 <para> 604 It's customary that messages meant for one specific person on an IRC channel are prepended by his/her alias followed by a colon ':'. BitlBee does this by default. If you prefer a different character, you can set it using <emphasis>set to_char</emphasis>. 605 </para> 606 607 <para> 608 Please note that this setting is only used for incoming messages. For outgoing messages you can use ':' (colon) or ',' to separate the destination nick from the message, and this is not configurable. 609 </para> 610 </description> 611 </bitlbee-setting> 612 613 <bitlbee-setting name="typing_notice" type="boolean" scope="global"> 614 <default>false</default> 615 616 <description> 617 <para> 618 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. ;-) 619 </para> 620 </description> 621 </bitlbee-setting> 622 623 <bitlbee-setting name="web_aware" type="string" scope="account"> 624 <default>false</default> 625 626 <description> 627 <para> 628 ICQ allows people to see if you're on-line via a CGI-script. (http://status.icq.com/online.gif?icq=UIN) This can be nice to put on your website, but it seems that spammers also use it to see if you're online without having to add you to their contact list. So to prevent ICQ spamming, recent versions of BitlBee disable this feature by default. 629 </para> 630 631 <para> 632 Unless you really intend to use this feature somewhere (on forums or maybe a website), it's probably better to keep this setting disabled. 633 </para> 634 </description> 547 635 </bitlbee-setting> 548 636 … … 674 762 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. 675 763 </para> 764 765 <para> 766 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. 767 </para> 676 768 </description> 677 769 -
doc/user-guide/help.xsl
rf4aa393 rd8d63a2 7 7 version="1.1"> 8 8 9 <xsl:output method="text" encoding=" iso-8859-1" standalone="yes"/>9 <xsl:output method="text" encoding="utf-8" standalone="yes"/> 10 10 <xsl:strip-space elements="*"/> 11 11 … … 58 58 <xsl:text>?set </xsl:text><xsl:value-of select="@name"/><xsl:text> </xsl:text> 59 59 <xsl:text>_b_Type:_b_ </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text> 60 <xsl:text>_b_Default:_b_ </xsl:text><xsl:value-of select="default"/><xsl:text> </xsl:text> 60 <xsl:text>_b_Scope:_b_ </xsl:text><xsl:value-of select="@scope"/><xsl:text> </xsl:text> 61 <xsl:if test="default"> 62 <xsl:text>_b_Default:_b_ </xsl:text><xsl:value-of select="default"/><xsl:text> </xsl:text> 63 </xsl:if> 61 64 <xsl:if test="possible-values"> 62 65 <xsl:text>_b_Possible Values:_b_ </xsl:text><xsl:value-of select="possible-values"/><xsl:text> </xsl:text> -
ipc.c
rf4aa393 rd8d63a2 99 99 { "die", 0, ipc_master_cmd_die, 0 }, 100 100 { "wallops", 1, NULL, IPC_CMD_TO_CHILDREN }, 101 { " lilo", 1, NULL, IPC_CMD_TO_CHILDREN },101 { "wall", 1, NULL, IPC_CMD_TO_CHILDREN }, 102 102 { "opermsg", 1, NULL, IPC_CMD_TO_CHILDREN }, 103 103 { "rehash", 0, ipc_master_cmd_rehash, 0 }, … … 122 122 } 123 123 124 static void ipc_child_cmd_ lilo( irc_t *irc, char **cmd )124 static void ipc_child_cmd_wall( irc_t *irc, char **cmd ) 125 125 { 126 126 if( !( irc->status & USTATUS_LOGGED_IN ) ) … … 175 175 { "die", 0, ipc_child_cmd_die, 0 }, 176 176 { "wallops", 1, ipc_child_cmd_wallops, 0 }, 177 { " lilo", 1, ipc_child_cmd_lilo, 0 },177 { "wall", 1, ipc_child_cmd_wall, 0 }, 178 178 { "opermsg", 1, ipc_child_cmd_opermsg, 0 }, 179 179 { "rehash", 0, ipc_child_cmd_rehash, 0 }, -
irc.c
rf4aa393 rd8d63a2 33 33 GSList *irc_connection_list = NULL; 34 34 35 static char *passchange (irc_t *irc, void *set, char *value) 36 { 37 irc_setpass (irc, value); 38 return (NULL); 35 static char *passchange( set_t *set, char *value ) 36 { 37 irc_t *irc = set->data; 38 39 irc_setpass( irc, value ); 40 irc_usermsg( irc, "Password successfully changed" ); 41 return NULL; 39 42 } 40 43 … … 46 49 char buf[128]; 47 50 #ifdef IPV6 48 struct sockaddr_in6 sock[1]; 49 #else 51 struct sockaddr_in6 sock6[1]; 52 unsigned int i6; 53 #endif 50 54 struct sockaddr_in sock[1]; 51 #endif52 55 53 56 irc = g_new0( irc_t, 1 ); … … 69 72 70 73 i = sizeof( *sock ); 74 #ifdef IPV6 75 i6 = sizeof( *sock6 ); 76 #endif 71 77 72 78 if( global.conf->hostname ) 73 79 irc->myhost = g_strdup( global.conf->hostname ); 74 80 #ifdef IPV6 75 else if( getsockname( irc->fd, (struct sockaddr*) sock , &i ) == 0 && sock->sin6_family == AF_INETx)76 { 77 if( ( peer = gethostbyaddr( (char*) &sock ->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx) ) )81 else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) 82 { 83 if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) 78 84 irc->myhost = g_strdup( peer->h_name ); 79 else if( inet_ntop( AF_INET x, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )85 else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) 80 86 irc->myhost = g_strdup( ipv6_unwrap( buf ) ); 81 87 } 82 #e lse83 else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET x)84 { 85 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET x) ) )88 #endif 89 else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) 90 { 91 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) 86 92 irc->myhost = g_strdup( peer->h_name ); 87 else if( inet_ntop( AF_INET x, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )93 else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) 88 94 irc->myhost = g_strdup( buf ); 89 95 } 90 #endif91 96 92 97 i = sizeof( *sock ); 93 98 #ifdef IPV6 94 if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx ) 95 { 96 if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) 99 i6 = sizeof( *sock6 ); 100 if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) 101 { 102 if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) 97 103 irc->host = g_strdup( peer->h_name ); 98 else if( inet_ntop( AF_INET x, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )104 else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) 99 105 irc->host = g_strdup( ipv6_unwrap( buf ) ); 100 106 } 101 #else 102 if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) 103 { 104 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) ) 107 else 108 #endif 109 if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) 110 { 111 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) 105 112 irc->host = g_strdup( peer->h_name ); 106 else if( inet_ntop( AF_INET x, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )113 else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) 107 114 irc->host = g_strdup( buf ); 108 115 } 109 #endif110 116 111 117 /* Rare, but possible. */ … … 120 126 irc_connection_list = g_slist_append( irc_connection_list, irc ); 121 127 122 set_add( irc, "away_devoice", "true", set_eval_away_devoice);123 set_add( irc, "auto_connect", "true", set_eval_bool);124 set_add( irc, "auto_reconnect", "false", set_eval_bool);125 set_add( irc, "auto_reconnect_delay", "300", set_eval_int);126 set_add( irc, "buddy_sendbuffer", "false", set_eval_bool);127 set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int);128 set_add( irc, "charset", "iso8859-1", set_eval_charset);129 set_add( irc, "debug", "false", set_eval_bool);130 set_add( irc, "default_target", "root", NULL);131 set_add( irc, "display_namechanges", "false", set_eval_bool);132 set_add( irc, "handle_unknown", "root", NULL);133 set_add( irc, "lcnicks", "true", set_eval_bool);134 set_add( irc, "ops", "both", set_eval_ops);135 set_add( irc, "private", "true", set_eval_bool);136 set_add( irc, "query_order", "lifo", NULL);137 set_add( irc, "save_on_quit", "true", set_eval_bool);138 set_add( irc, "strip_html", "true", NULL);139 set_add( irc, "to_char", ": ", set_eval_to_char);140 set_add( irc, "typing_notice", "false", set_eval_bool);141 set_add( irc, "password", NULL, passchange);128 set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); 129 set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); 130 set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); 131 set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc ); 132 set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 133 set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 134 set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc ); 135 set_add( &irc->set, "debug", "false", set_eval_bool, irc ); 136 set_add( &irc->set, "default_target", "root", NULL, irc ); 137 set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); 138 set_add( &irc->set, "handle_unknown", "root", NULL, irc ); 139 set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); 140 set_add( &irc->set, "ops", "both", set_eval_ops, irc ); 141 set_add( &irc->set, "password", NULL, passchange, irc ); 142 set_add( &irc->set, "private", "true", set_eval_bool, irc ); 143 set_add( &irc->set, "query_order", "lifo", NULL, irc ); 144 set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 145 set_add( &irc->set, "strip_html", "true", NULL, irc ); 146 set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); 147 set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); 142 148 143 149 conf_loaddefaults( irc ); … … 203 209 void irc_free(irc_t * irc) 204 210 { 205 account_t *account , *accounttmp;211 account_t *account; 206 212 user_t *user, *usertmp; 207 nick_t *nick, *nicktmp;208 213 help_t *helpnode, *helpnodetmp; 209 set_t *setnode, *setnodetmp;210 214 211 215 log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); 212 216 213 if( irc->status & USTATUS_IDENTIFIED && set_get int( irc, "save_on_quit" ) )217 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 214 218 if( storage_save( irc, TRUE ) != STORAGE_OK ) 215 219 irc_usermsg( irc, "Error while saving settings!" ); … … 251 255 query_del(irc, irc->queries); 252 256 253 if (irc->accounts != NULL) { 254 account = irc->accounts; 255 while (account != NULL) { 256 g_free(account->user); 257 g_free(account->pass); 258 g_free(account->server); 259 accounttmp = account; 260 account = account->next; 261 g_free(accounttmp); 262 } 263 } 257 while (irc->accounts) 258 account_del(irc, irc->accounts); 259 260 while (irc->set) 261 set_del(&irc->set, irc->set->key); 264 262 265 263 if (irc->users != NULL) { … … 286 284 g_hash_table_destroy(irc->watches); 287 285 288 if (irc->nicks != NULL) {289 nick = irc->nicks;290 while (nick != NULL) {291 g_free(nick->nick);292 g_free(nick->handle);293 294 nicktmp = nick;295 nick = nick->next;296 g_free(nicktmp);297 }298 }299 286 if (irc->help != NULL) { 300 287 helpnode = irc->help; … … 307 294 } 308 295 } 309 if (irc->set != NULL) {310 setnode = irc->set;311 while (setnode != NULL) {312 g_free(setnode->key);313 g_free(setnode->def);314 g_free(setnode->value);315 316 setnodetmp = setnode;317 setnode = setnode->next;318 g_free(setnodetmp);319 }320 }321 296 g_free(irc); 322 297 … … 329 304 void irc_setpass (irc_t *irc, const char *pass) 330 305 { 331 if (irc->password)g_free (irc->password);306 g_free (irc->password); 332 307 333 308 if (pass) { 334 309 irc->password = g_strdup (pass); 335 irc_usermsg (irc, "Password successfully changed");336 310 } else { 337 311 irc->password = NULL; … … 364 338 } 365 339 366 if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )340 if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) 367 341 { 368 342 conv[IRC_MAX_LINE] = 0; … … 584 558 585 559 strip_newlines( line ); 586 if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )560 if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) 587 561 { 588 562 char conv[IRC_MAX_LINE+1]; … … 611 585 the queue. If it's FALSE, we emptied the buffer and saved ourselves some work 612 586 in the event queue. */ 613 if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) 614 irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); 587 /* Really can't be done as long as the code doesn't do error checking very well: 588 if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) */ 589 590 /* So just always do it via the event handler. */ 591 irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); 615 592 } 616 593 … … 652 629 char namelist[385] = ""; 653 630 struct conversation *c = NULL; 631 char *ops = set_getstr( &irc->set, "ops" ); 654 632 655 633 /* RFCs say there is no error reply allowed on NAMES, so when the … … 666 644 } 667 645 668 if( u->gc && !u->away && set_get int( irc, "away_devoice" ) )646 if( u->gc && !u->away && set_getbool( &irc->set, "away_devoice" ) ) 669 647 strcat( namelist, "+" ); 648 else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || 649 ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) 650 strcat( namelist, "@" ); 670 651 671 652 strcat( namelist, u->nick ); … … 676 657 { 677 658 GList *l; 678 char *ops = set_getstr( irc, "ops" );679 659 680 660 /* root and the user aren't in the channel userlist but should … … 924 904 { 925 905 char *nick, *s; 926 char reason[ 64];906 char reason[128]; 927 907 928 908 if( u->gc && u->gc->flags & OPT_LOGGING_OUT ) 929 909 { 930 if( u->gc-> user->proto_opt[0][0])910 if( u->gc->acc->server ) 931 911 g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, 932 u->gc-> user->proto_opt[0]);912 u->gc->acc->server ); 933 913 else if( ( s = strchr( u->gc->username, '@' ) ) ) 934 914 g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, … … 936 916 else 937 917 g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost, 938 u->gc-> prpl->name, irc->myhost );918 u->gc->acc->prpl->name, irc->myhost ); 939 919 940 920 /* proto_opt might contain garbage after the : */ … … 1012 992 else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 ) 1013 993 { 1014 if( u && u->gc && u->gc-> prpl->send_typing && strlen( s ) >= 10 )994 if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 ) 1015 995 { 1016 996 time_t current_typing_notice = time( NULL ); … … 1018 998 if( current_typing_notice - u->last_typing_notice >= 5 ) 1019 999 { 1020 u->gc-> prpl->send_typing( u->gc, u->handle, s[8] == '1' );1000 u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' ); 1021 1001 u->last_typing_notice = current_typing_notice; 1022 1002 } … … 1051 1031 } 1052 1032 } 1053 else if( c && c->gc && c->gc-> prpl )1033 else if( c && c->gc && c->gc->acc && c->gc->acc->prpl ) 1054 1034 { 1055 1035 return( bim_chat_msg( c->gc, c->id, s ) ); … … 1083 1063 if( !u || !u->gc ) return; 1084 1064 1085 if( set_get int( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )1065 if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) 1086 1066 { 1087 1067 int delay; … … 1110 1090 strcat( u->sendbuf, "\n" ); 1111 1091 1112 delay = set_getint( irc, "buddy_sendbuffer_delay" );1092 delay = set_getint( &irc->set, "buddy_sendbuffer_delay" ); 1113 1093 if( delay <= 5 ) 1114 1094 delay *= 1000; … … 1175 1155 int len = strlen( irc->nick) + 3; 1176 1156 prefix = g_new (char, len ); 1177 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );1157 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) ); 1178 1158 prefix[len-1] = 0; 1179 1159 } -
irc.h
rf4aa393 rd8d63a2 98 98 99 99 #include "user.h" 100 #include "nick.h"100 // #include "nick.h" 101 101 102 102 extern GSList *irc_connection_list; -
irc_commands.c
rf4aa393 rd8d63a2 150 150 irc_part( irc, u, c->channel ); 151 151 152 if( c->gc && c->gc->prpl)152 if( c->gc ) 153 153 { 154 154 c->joined = 0; 155 c->gc-> prpl->chat_leave( c->gc, c->id );155 c->gc->acc->prpl->chat_leave( c->gc, c->id ); 156 156 } 157 157 } … … 173 173 user_t *u = user_find( irc, cmd[1] + 1 ); 174 174 175 if( u && u->gc && u->gc-> prpl && u->gc->prpl->chat_open )175 if( u && u->gc && u->gc->acc->prpl->chat_open ) 176 176 { 177 177 irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] ); 178 178 179 if( !u->gc-> prpl->chat_open( u->gc, u->handle ) )179 if( !u->gc->acc->prpl->chat_open( u->gc, u->handle ) ) 180 180 { 181 181 irc_usermsg( irc, "Could not open a groupchat with %s.", u->nick ); … … 205 205 206 206 if( u && c && ( u->gc == c->gc ) ) 207 if( c->gc && c->gc-> prpl && c->gc->prpl->chat_invite )208 { 209 c->gc-> prpl->chat_invite( c->gc, c->id, "", u->handle );207 if( c->gc && c->gc->acc->prpl->chat_invite ) 208 { 209 c->gc->acc->prpl->chat_invite( c->gc, c->id, "", u->handle ); 210 210 irc_reply( irc, 341, "%s %s", nick, channel ); 211 211 return; … … 230 230 { 231 231 unsigned int i; 232 char *t = set_getstr( irc, "default_target" );232 char *t = set_getstr( &irc->set, "default_target" ); 233 233 234 234 if( g_strcasecmp( t, "last" ) == 0 && irc->last_target ) … … 477 477 478 478 if( u->gc ) 479 irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username, 480 *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name ); 479 irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->acc->user, 480 u->gc->acc->server && *u->gc->acc->server ? u->gc->acc->server : "", 481 u->gc->acc->prpl->name ); 481 482 else 482 483 irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO ); … … 592 593 { "die", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 593 594 { "wallops", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 594 { " lilo", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },595 { "wall", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 595 596 { "rehash", 0, irc_cmd_rehash, IRC_CMD_OPER_ONLY }, 596 597 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, -
lib/events.h
rf4aa393 rd8d63a2 20 20 */ 21 21 22 /* 23 * Split off the event handling things from proxy.[ch] (and adding timer 24 * stuff. This to allow BitlBee to use other libs than GLib for event 25 * handling. 26 */ 22 /* This stuff used to be in proxy.c too, but I split it off so BitlBee can 23 use other libraries (like libevent) to handle events. proxy.c is one very 24 nice piece of work from Gaim. It connects to a TCP server in the back- 25 ground and calls a callback function once the connection is ready to use. 26 This function (proxy_connect()) can be found in proxy.c. (It also 27 transparently handles HTTP/SOCKS proxies, when necessary.) 28 29 This file offers some extra event handling toys, which will be handled 30 by GLib or libevent. The advantage of using libevent is that it can use 31 more advanced I/O polling functions like epoll() in recent Linux 32 kernels. This should improve BitlBee's scalability. */ 27 33 28 34 … … 39 45 #include <gmodule.h> 40 46 47 /* The conditions you can pass to gaim_input_add()/that will be passed to 48 the given callback function. */ 41 49 typedef enum { 42 50 GAIM_INPUT_READ = 1 << 1, … … 45 53 typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond); 46 54 55 /* For internal use. */ 47 56 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) 48 57 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) … … 52 61 #define event_debug( x... ) 53 62 63 /* Call this once when the program starts. It'll initialize the event handler 64 library (if necessary) and then return immediately. */ 54 65 G_MODULE_EXPORT void b_main_init(); 66 67 /* This one enters the event loop. It shouldn't return until one of the event 68 handlers calls b_main_quit(). */ 55 69 G_MODULE_EXPORT void b_main_run(); 56 70 G_MODULE_EXPORT void b_main_quit(); 57 71 72 73 /* Add event handlers (for I/O or a timeout). The event handler will be called 74 every time the event "happens", until your event handler returns FALSE (or 75 until you remove it using b_event_remove(). As usual, the data argument 76 can be used to pass your own data to the event handler. */ 58 77 G_MODULE_EXPORT gint b_input_add(int fd, b_input_condition cond, b_event_handler func, gpointer data); 59 78 G_MODULE_EXPORT gint b_timeout_add(gint timeout, b_event_handler func, gpointer data); 60 79 G_MODULE_EXPORT void b_event_remove(gint id); 61 80 81 /* For now, closesocket() is only a function when using libevent. With GLib 82 it's a preprocessor macro. */ 62 83 #ifdef EVENTS_LIBEVENT 63 84 G_MODULE_EXPORT void closesocket(int fd); -
lib/events_glib.c
rf4aa393 rd8d63a2 122 122 gint b_timeout_add(gint timeout, b_event_handler func, gpointer data) 123 123 { 124 gint st = g_timeout_add(timeout, func, data); 124 /* GSourceFunc and the BitlBee event handler function aren't 125 really the same, but they're "compatible". ;-) It will do 126 for now, BitlBee only looks at the "data" argument. */ 127 gint st = g_timeout_add(timeout, (GSourceFunc) func, data); 125 128 126 129 event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st ); -
lib/events_libevent.c
rf4aa393 rd8d63a2 101 101 102 102 /* Since the called function might cancel this handler already 103 (which free()s b_ev , we have to remember the ID here. */103 (which free()s b_ev), we have to remember the ID here. */ 104 104 id = b_ev->id; 105 105 -
lib/misc.c
rf4aa393 rd8d63a2 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-200 4Wilmer van der Gaast and others *4 * Copyright 2002-2006 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 11 11 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> 12 12 * (and possibly other members of the Gaim team) 13 * Copyright 2002-200 5Wilmer van der Gaast <wilmer@gaast.net>13 * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net> 14 14 */ 15 15 … … 54 54 } 55 55 56 char *add_cr(char *text)57 {58 char *ret = NULL;59 int count = 0, j;60 unsigned int i;61 62 if (text[0] == '\n')63 count++;64 for (i = 1; i < strlen(text); i++)65 if (text[i] == '\n' && text[i - 1] != '\r')66 count++;67 68 if (count == 0)69 return g_strdup(text);70 71 ret = g_malloc0(strlen(text) + count + 1);72 73 i = 0; j = 0;74 if (text[i] == '\n')75 ret[j++] = '\r';76 ret[j++] = text[i++];77 for (; i < strlen(text); i++) {78 if (text[i] == '\n' && text[i - 1] != '\r')79 ret[j++] = '\r';80 ret[j++] = text[i];81 }82 83 return ret;84 }85 86 static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";87 88 /* XXX Find bug */89 char *tobase64(const char *text)90 {91 char *out = NULL;92 const char *c;93 unsigned int tmp = 0;94 int len = 0, n = 0;95 96 c = text;97 98 while (*c) {99 tmp = tmp << 8;100 tmp += *c;101 n++;102 103 if (n == 3) {104 out = g_realloc(out, len + 4);105 out[len] = alphabet[(tmp >> 18) & 0x3f];106 out[len + 1] = alphabet[(tmp >> 12) & 0x3f];107 out[len + 2] = alphabet[(tmp >> 6) & 0x3f];108 out[len + 3] = alphabet[tmp & 0x3f];109 len += 4;110 tmp = 0;111 n = 0;112 }113 c++;114 }115 switch (n) {116 117 case 2:118 tmp <<= 8;119 out = g_realloc(out, len + 5);120 out[len] = alphabet[(tmp >> 18) & 0x3f];121 out[len + 1] = alphabet[(tmp >> 12) & 0x3f];122 out[len + 2] = alphabet[(tmp >> 6) & 0x3f];123 out[len + 3] = '=';124 out[len + 4] = 0;125 break;126 case 1:127 tmp <<= 16;128 out = g_realloc(out, len + 5);129 out[len] = alphabet[(tmp >> 18) & 0x3f];130 out[len + 1] = alphabet[(tmp >> 12) & 0x3f];131 out[len + 2] = '=';132 out[len + 3] = '=';133 out[len + 4] = 0;134 break;135 case 0:136 out = g_realloc(out, len + 1);137 out[len] = 0;138 break;139 }140 return out;141 }142 143 56 char *normalize(const char *s) 144 57 { … … 181 94 typedef struct htmlentity 182 95 { 183 char code[ 8];184 char is[ 4];96 char code[7]; 97 char is[3]; 185 98 } htmlentity_t; 186 187 /* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */188 99 189 100 static const htmlentity_t ent[] = … … 479 390 } 480 391 481 char *set_eval_charset( irc_t *irc, set_t *set, char *value ) 482 { 483 GIConv cd; 484 485 if ( g_strncasecmp( value, "none", 4 ) == 0 ) 486 return( value ); 487 488 cd = g_iconv_open( "UTF-8", value ); 489 if( cd == (GIConv) -1 ) 490 return( NULL ); 491 492 g_iconv_close( cd ); 493 return( value ); 494 } 392 /* A pretty reliable random number generator. Tries to use the /dev/random 393 devices first, and falls back to the random number generator from libc 394 when it fails. Opens randomizer devices with O_NONBLOCK to make sure a 395 lack of entropy won't halt BitlBee. */ 396 void random_bytes( unsigned char *buf, int count ) 397 { 398 static int use_dev = -1; 399 400 /* Actually this probing code isn't really necessary, is it? */ 401 if( use_dev == -1 ) 402 { 403 if( access( "/dev/random", R_OK ) == 0 || access( "/dev/urandom", R_OK ) == 0 ) 404 use_dev = 1; 405 else 406 { 407 use_dev = 0; 408 srand( ( getpid() << 16 ) ^ time( NULL ) ); 409 } 410 } 411 412 if( use_dev ) 413 { 414 int fd; 415 416 /* At least on Linux, /dev/random can block if there's not 417 enough entropy. We really don't want that, so if it can't 418 give anything, use /dev/urandom instead. */ 419 if( ( fd = open( "/dev/random", O_RDONLY | O_NONBLOCK ) ) >= 0 ) 420 if( read( fd, buf, count ) == count ) 421 { 422 close( fd ); 423 return; 424 } 425 close( fd ); 426 427 /* urandom isn't supposed to block at all, but just to be 428 sure. If it blocks, we'll disable use_dev and use the libc 429 randomizer instead. */ 430 if( ( fd = open( "/dev/urandom", O_RDONLY | O_NONBLOCK ) ) >= 0 ) 431 if( read( fd, buf, count ) == count ) 432 { 433 close( fd ); 434 return; 435 } 436 close( fd ); 437 438 /* If /dev/random blocks once, we'll still try to use it 439 again next time. If /dev/urandom also fails for some 440 reason, stick with libc during this session. */ 441 442 use_dev = 0; 443 srand( ( getpid() << 16 ) ^ time( NULL ) ); 444 } 445 446 if( !use_dev ) 447 { 448 int i; 449 450 /* Possibly the LSB of rand() isn't very random on some 451 platforms. Seems okay on at least Linux and OSX though. */ 452 for( i = 0; i < count; i ++ ) 453 buf[i] = rand() & 0xff; 454 } 455 } 456 457 int is_bool( char *value ) 458 { 459 if( *value == 0 ) 460 return 0; 461 462 if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) 463 return 1; 464 if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) 465 return 1; 466 467 while( *value ) 468 if( !isdigit( *value ) ) 469 return 0; 470 else 471 value ++; 472 473 return 1; 474 } 475 476 int bool2int( char *value ) 477 { 478 int i; 479 480 if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) 481 return 1; 482 if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) 483 return 0; 484 485 if( sscanf( value, "%d", &i ) == 1 ) 486 return i; 487 488 return 0; 489 } -
lib/misc.h
rf4aa393 rd8d63a2 24 24 */ 25 25 26 #ifndef _UTIL_H 27 #define _UTIL_H 26 #ifndef _MISC_H 27 #define _MISC_H 28 29 #include <gmodule.h> 30 #include <time.h> 28 31 29 32 G_MODULE_EXPORT void strip_linefeed( gchar *text ); 30 33 G_MODULE_EXPORT char *add_cr( char *text ); 31 34 G_MODULE_EXPORT char *strip_newlines(char *source); 32 G_MODULE_EXPORT char *tobase64( const char *text );33 35 G_MODULE_EXPORT char *normalize( const char *s ); 34 36 G_MODULE_EXPORT void info_string_append( GString *str, char *newline, char *name, char *value ); … … 46 48 47 49 G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf ); 48 char *set_eval_charset( irc_t *irc, set_t *set, char *value ); 50 51 G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count ); 52 53 G_MODULE_EXPORT int is_bool( char *value ); 54 G_MODULE_EXPORT int bool2int( char *value ); 49 55 50 56 #endif -
lib/proxy.c
rf4aa393 rd8d63a2 41 41 #include "nogaim.h" 42 42 #include "proxy.h" 43 #include "base64.h" 43 44 44 45 char proxyhost[128] = ""; -
lib/ssl_client.h
rf4aa393 rd8d63a2 24 24 */ 25 25 26 /* ssl_client makes it easier to open SSL connections to servers. (It 27 doesn't offer SSL server functionality yet, but it could be useful 28 to add it later.) Different ssl_client modules are available, and 29 ssl_client tries to make them all behave the same. It's very simple 30 and basic, it just imitates the proxy_connect() function from the 31 Gaim libs and passes the socket to the program once the handshake 32 is completed. */ 33 26 34 #include <glib.h> 27 35 #include "proxy.h" 28 36 37 /* Some generic error codes. Especially SSL_AGAIN is important if you 38 want to do asynchronous I/O. */ 29 39 #define SSL_OK 0 30 40 #define SSL_NOHANDSHAKE 1 … … 33 43 extern int ssl_errno; 34 44 45 /* This is what your callback function should look like. */ 35 46 typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition); 36 47 48 49 /* Connect to host:port, call the given function when the connection is 50 ready to be used for SSL traffic. This is all done asynchronously, no 51 blocking I/O! (Except for the DNS lookups, for now...) */ 37 52 G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ); 53 54 /* Obviously you need special read/write functions to read data. */ 38 55 G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len ); 39 56 G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); 57 58 /* Abort the SSL connection and disconnect the socket. Do not use close() 59 directly, both the SSL library and the peer will be unhappy! */ 40 60 G_MODULE_EXPORT void ssl_disconnect( void *conn_ ); 61 62 /* Get the fd for this connection, you will usually need it for event 63 handling. */ 41 64 G_MODULE_EXPORT int ssl_getfd( void *conn ); 65 66 /* This function returns GAIM_INPUT_READ/WRITE. With SSL connections it's 67 possible that something has to be read while actually were trying to 68 write something (think about key exchange/refresh/etc). So when an 69 SSL operation returned SSL_AGAIN, *always* use this function when 70 adding an event handler to the queue. (And it should perform exactly 71 the same action as the handler that just received the SSL_AGAIN.) */ 42 72 G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn ); -
nick.c
rf4aa393 rd8d63a2 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-200 4Wilmer van der Gaast and others *4 * Copyright 2002-2006 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 27 27 #include "bitlbee.h" 28 28 29 void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick ) 30 { 31 nick_t *m = NULL, *n = irc->nicks; 32 33 while( n ) 34 { 35 if( ( g_strcasecmp( n->handle, handle ) == 0 ) && n->proto == proto ) 36 { 37 g_free( n->nick ); 38 n->nick = nick_dup( nick ); 39 nick_strip( n->nick ); 40 41 return; 42 } 43 n = ( m = n )->next; // :-P 44 } 45 46 if( m ) 47 n = m->next = g_new0( nick_t, 1 ); 29 /* Store handles in lower case and strip spaces, because AIM is braindead. */ 30 static char *clean_handle( const char *orig ) 31 { 32 char *new = g_malloc( strlen( orig ) + 1 ); 33 int i = 0; 34 35 do { 36 if (*orig != ' ') 37 new[i++] = tolower( *orig ); 38 } 39 while (*(orig++)); 40 41 return new; 42 } 43 44 void nick_set( account_t *acc, const char *handle, const char *nick ) 45 { 46 char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 ); 47 48 store_handle = clean_handle( handle ); 49 strncpy( store_nick, nick, MAX_NICK_LENGTH ); 50 nick_strip( store_nick ); 51 52 g_hash_table_replace( acc->nicks, store_handle, store_nick ); 53 } 54 55 char *nick_get( account_t *acc, const char *handle, const char *realname ) 56 { 57 static char nick[MAX_NICK_LENGTH+1]; 58 char *store_handle, *found_nick; 59 int inf_protection = 256; 60 61 memset( nick, 0, MAX_NICK_LENGTH + 1 ); 62 63 store_handle = clean_handle( handle ); 64 /* Find out if we stored a nick for this person already. If not, try 65 to generate a sane nick automatically. */ 66 if( ( found_nick = g_hash_table_lookup( acc->nicks, store_handle ) ) ) 67 { 68 strncpy( nick, found_nick, MAX_NICK_LENGTH ); 69 } 48 70 else 49 n = irc->nicks = g_new0( nick_t, 1 );50 51 n->handle = g_strdup( handle );52 n->proto = proto;53 n->nick = nick_dup( nick );54 55 nick_strip( n->nick );56 }57 58 char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname )59 {60 static char nick[MAX_NICK_LENGTH+1];61 nick_t *n = irc->nicks;62 int inf_protection = 256;63 64 memset( nick, 0, MAX_NICK_LENGTH + 1 );65 66 while( n && !*nick )67 if( ( n->proto == proto ) && ( g_strcasecmp( n->handle, handle ) == 0 ) )68 strcpy( nick, n->nick );69 else70 n = n->next;71 72 if( !n )73 71 { 74 72 char *s; … … 86 84 87 85 nick_strip( nick ); 88 if (set_getint(irc, "lcnicks"))86 if( set_getbool( &acc->irc->set, "lcnicks" ) ) 89 87 nick_lc( nick ); 90 88 } 91 92 while( !nick_ok( nick ) || user_find( irc, nick ) ) 89 g_free( store_handle ); 90 91 /* Now, find out if the nick is already in use at the moment, and make 92 subtle changes to make it unique. */ 93 while( !nick_ok( nick ) || user_find( acc->irc, nick ) ) 93 94 { 94 95 if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) ) … … 106 107 int i; 107 108 108 irc_usermsg( irc, "WARNING: Almost had an infinite loop in nick_get()! "109 "This used to be a fatal BitlBee bug, but we tried to fix it. "110 "This message should *never* appear anymore. "111 "If it does, please *do* send us a bug report! "112 "Please send all the following lines in your report:" );113 114 irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle );109 irc_usermsg( acc->irc, "WARNING: Almost had an infinite loop in nick_get()! " 110 "This used to be a fatal BitlBee bug, but we tried to fix it. " 111 "This message should *never* appear anymore. " 112 "If it does, please *do* send us a bug report! " 113 "Please send all the following lines in your report:" ); 114 115 irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle ); 115 116 for( i = 0; i < MAX_NICK_LENGTH; i ++ ) 116 irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );117 118 irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "119 "Good luck, and please don't forget to paste the lines up here "120 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );117 irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] ); 118 119 irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. " 120 "Good luck, and please don't forget to paste the lines up here " 121 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" ); 121 122 122 123 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); … … 126 127 } 127 128 128 return( nick ); 129 } 130 131 void nick_del( irc_t *irc, const char *nick ) 132 { 133 nick_t *l = NULL, *n = irc->nicks; 134 135 while( n ) 136 { 137 if( g_strcasecmp( n->nick, nick ) == 0 ) 138 { 139 if( l ) 140 l->next = n->next; 141 else 142 irc->nicks = n->next; 143 144 g_free( n->handle ); 145 g_free( n->nick ); 146 g_free( n ); 147 148 break; 149 } 150 n = (l=n)->next; 151 } 129 return nick; 130 } 131 132 void nick_del( account_t *acc, const char *handle ) 133 { 134 g_hash_table_remove( acc->nicks, handle ); 152 135 } 153 136 -
nick.h
rf4aa393 rd8d63a2 24 24 */ 25 25 26 typedef struct __NICK 27 { 28 char *handle; 29 struct prpl *proto; 30 char *nick; 31 struct __NICK *next; 32 } nick_t; 33 34 void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick ); 35 char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname ); 36 void nick_del( irc_t *irc, const char *nick ); 26 void nick_set( account_t *acc, const char *handle, const char *nick ); 27 char *nick_get( account_t *acc, const char *handle, const char *realname ); 28 void nick_del( account_t *acc, const char *handle ); 37 29 void nick_strip( char *nick ); 38 30 -
protocols/Makefile
rf4aa393 rd8d63a2 10 10 11 11 # [SH] Program variables 12 objects = $(EVENT_HANDLER) http_client.o md5.o nogaim.o proxy.o sha.o $(SSL_CLIENT)12 objects = nogaim.o 13 13 14 14 # [SH] The next two lines should contain the directory name (in $(subdirs)) -
protocols/jabber/jabber.c
rf4aa393 rd8d63a2 561 561 static void gjab_start(gjconn gjc) 562 562 { 563 struct aim_user *user;563 account_t *acc; 564 564 int port = -1, ssl = 0; 565 char *server = NULL , *s;565 char *server = NULL; 566 566 567 567 if (!gjc || gjc->state != JCONN_STATE_OFF) 568 568 return; 569 569 570 user = GJ_GC(gjc)->user; 571 if (*user->proto_opt[0]) { 572 /* If there's a dot, assume there's a hostname in the beginning */ 573 if (strchr(user->proto_opt[0], '.')) { 574 server = g_strdup(user->proto_opt[0]); 575 if ((s = strchr(server, ':'))) 576 *s = 0; 577 } 578 579 /* After the hostname, there can be a port number */ 580 s = strchr(user->proto_opt[0], ':'); 581 if (s && isdigit(s[1])) 582 sscanf(s + 1, "%d", &port); 583 584 /* And if there's the string ssl, the user wants an SSL-connection */ 585 if (strstr(user->proto_opt[0], ":ssl") || g_strcasecmp(user->proto_opt[0], "ssl") == 0) 586 ssl = 1; 587 } 588 589 if (port == -1 && !ssl) 590 port = DEFAULT_PORT; 591 else if (port == -1 && ssl) 592 port = DEFAULT_PORT_SSL; 593 else if (port < JABBER_PORT_MIN || port > JABBER_PORT_MAX) { 570 acc = GJ_GC(gjc)->acc; 571 server = acc->server; 572 port = set_getint(&acc->set, "port"); 573 ssl = set_getbool(&acc->set, "ssl"); 574 575 if (port < JABBER_PORT_MIN || port > JABBER_PORT_MAX) { 594 576 serv_got_crap(GJ_GC(gjc), "For security reasons, the Jabber port number must be in the %d-%d range.", JABBER_PORT_MIN, JABBER_PORT_MAX); 595 577 STATE_EVT(JCONN_STATE_OFF) … … 614 596 } 615 597 616 g_free(server); 617 618 if (!user->gc || (gjc->fd < 0)) { 598 if (!acc->gc || (gjc->fd < 0)) { 619 599 STATE_EVT(JCONN_STATE_OFF) 620 600 return; … … 1516 1496 } 1517 1497 1518 static void jabber_login(struct aim_user *user) 1519 { 1520 struct gaim_connection *gc = new_gaim_conn(user); 1521 struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1); 1522 char *loginname = create_valid_jid(user->username, DEFAULT_SERVER, "BitlBee"); 1523 1498 static void jabber_acc_init(account_t *acc) 1499 { 1500 set_t *s; 1501 1502 s = set_add( &acc->set, "port", "5222", set_eval_int, acc ); 1503 s->flags |= ACC_SET_OFFLINE_ONLY; 1504 1505 s = set_add( &acc->set, "resource", "BitlBee", NULL, acc ); 1506 s->flags |= ACC_SET_OFFLINE_ONLY; 1507 1508 s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); 1509 s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; 1510 1511 s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc ); 1512 s->flags |= ACC_SET_OFFLINE_ONLY; 1513 } 1514 1515 static void jabber_login(account_t *acc) 1516 { 1517 struct gaim_connection *gc; 1518 struct jabber_data *jd; 1519 char *resource, *loginname; 1520 1521 /* Time to move some data/things from the old syntax to the new one: */ 1522 if (acc->server) { 1523 char *s, *tmp_server; 1524 int port; 1525 1526 if (g_strcasecmp(acc->server, "ssl") == 0) { 1527 set_setstr(&acc->set, "server", ""); 1528 set_setint(&acc->set, "port", DEFAULT_PORT_SSL); 1529 set_setstr(&acc->set, "ssl", "true"); 1530 1531 g_free(acc->server); 1532 acc->server = NULL; 1533 } else if ((s = strchr(acc->server, ':'))) { 1534 if (strstr(acc->server, ":ssl")) { 1535 set_setint(&acc->set, "port", DEFAULT_PORT_SSL); 1536 set_setstr(&acc->set, "ssl", "true"); 1537 } 1538 if (isdigit(s[1])) { 1539 if (sscanf(s + 1, "%d", &port) == 1) 1540 set_setint(&acc->set, "port", port); 1541 } 1542 tmp_server = g_strndup(acc->server, s - acc->server); 1543 set_setstr(&acc->set, "server", tmp_server); 1544 g_free(tmp_server); 1545 } 1546 } 1547 1548 gc = new_gaim_conn(acc); 1549 jd = gc->proto_data = g_new0(struct jabber_data, 1); 1550 1551 if( strchr( acc->user, '@' ) == NULL ) 1552 { 1553 hide_login_progress( gc, "Invalid account name" ); 1554 signoff( gc ); 1555 return; 1556 } 1557 1558 resource = set_getstr(&acc->set, "resource"); 1559 loginname = create_valid_jid(acc->user, DEFAULT_SERVER, resource); 1560 1524 1561 jd->hash = g_hash_table_new(g_str_hash, g_str_equal); 1525 1562 jd->chats = NULL; /* we have no chats yet */ … … 1527 1564 set_login_progress(gc, 1, _("Connecting")); 1528 1565 1529 if (!(jd->gjc = gjab_new(loginname, user->password, gc))) {1566 if (!(jd->gjc = gjab_new(loginname, acc->pass, gc))) { 1530 1567 g_free(loginname); 1531 1568 hide_login_progress(gc, _("Unable to connect")); … … 2337 2374 ret->name = "jabber"; 2338 2375 ret->away_states = jabber_away_states; 2376 ret->acc_init = jabber_acc_init; 2339 2377 ret->login = jabber_login; 2340 2378 ret->close = jabber_close; … … 2349 2387 ret->alias_buddy = jabber_roster_update; 2350 2388 ret->group_buddy = jabber_group_change; 2351 ret-> cmp_buddynames= g_strcasecmp;2389 ret->handle_cmp = g_strcasecmp; 2352 2390 2353 2391 register_protocol (ret); -
protocols/msn/msn.c
rf4aa393 rd8d63a2 27 27 #include "msn.h" 28 28 29 static void msn_login( struct aim_user *acct ) 30 { 31 struct gaim_connection *gc = new_gaim_conn( acct ); 29 static char *msn_set_display_name( set_t *set, char *value ); 30 31 static void msn_acc_init( account_t *acc ) 32 { 33 set_t *s; 34 35 s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc ); 36 s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; 37 } 38 39 static void msn_login( account_t *acc ) 40 { 41 struct gaim_connection *gc = new_gaim_conn( acc ); 32 42 struct msn_data *md = g_new0( struct msn_data, 1 ); 33 34 set_login_progress( gc, 1, "Connecting" );35 43 36 44 gc->proto_data = md; 37 45 md->fd = -1; 38 46 39 if( strchr( acc t->username, '@' ) == NULL )47 if( strchr( acc->user, '@' ) == NULL ) 40 48 { 41 49 hide_login_progress( gc, "Invalid account name" ); … … 44 52 } 45 53 54 set_login_progress( gc, 1, "Connecting" ); 55 46 56 md->fd = proxy_connect( "messenger.hotmail.com", 1863, msn_ns_connected, gc ); 47 57 if( md->fd < 0 ) … … 49 59 hide_login_progress( gc, "Could not connect to server" ); 50 60 signoff( gc ); 51 } 52 else 53 { 54 md->gc = gc; 55 md->away_state = msn_away_state_list; 56 57 msn_connections = g_slist_append( msn_connections, gc ); 58 } 61 return; 62 } 63 64 md->gc = gc; 65 md->away_state = msn_away_state_list; 66 67 msn_connections = g_slist_append( msn_connections, gc ); 59 68 } 60 69 … … 212 221 static void msn_set_info( struct gaim_connection *gc, char *info ) 213 222 { 214 int i; 215 char buf[1024], *fn, *s; 216 struct msn_data *md = gc->proto_data; 217 218 if( strlen( info ) > 129 ) 219 { 220 do_error_dialog( gc, "Maximum name length exceeded", "MSN" ); 221 return; 222 } 223 224 /* Of course we could use http_encode() here, but when we encode 225 every character, the server is less likely to complain about the 226 chosen name. However, the MSN server doesn't seem to like escaped 227 non-ASCII chars, so we keep those unescaped. */ 228 s = fn = g_new0( char, strlen( info ) * 3 + 1 ); 229 for( i = 0; info[i]; i ++ ) 230 if( info[i] & 128 ) 231 { 232 *s = info[i]; 233 s ++; 234 } 235 else 236 { 237 g_snprintf( s, 4, "%%%02X", info[i] ); 238 s += 3; 239 } 240 241 g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn ); 242 msn_write( gc, buf, strlen( buf ) ); 243 g_free( fn ); 223 msn_set_display_name( set_find( &gc->acc->set, "display_name" ), info ); 244 224 } 245 225 … … 380 360 } 381 361 362 static char *msn_set_display_name( set_t *set, char *value ) 363 { 364 account_t *acc = set->data; 365 struct gaim_connection *gc = acc->gc; 366 struct msn_data *md; 367 char buf[1024], *fn; 368 369 /* Double-check. */ 370 if( gc == NULL ) 371 return NULL; 372 373 md = gc->proto_data; 374 375 if( strlen( value ) > 129 ) 376 { 377 serv_got_crap( gc, "Maximum name length exceeded" ); 378 return NULL; 379 } 380 381 fn = msn_http_encode( value ); 382 383 g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn ); 384 msn_write( gc, buf, strlen( buf ) ); 385 g_free( fn ); 386 387 /* Returning NULL would be better, because the server still has to 388 confirm the name change. However, it looks a bit confusing to the 389 user. */ 390 return value; 391 } 392 382 393 void msn_init() 383 394 { 384 395 struct prpl *ret = g_new0(struct prpl, 1); 396 385 397 ret->name = "msn"; 386 398 ret->login = msn_login; 399 ret->acc_init = msn_acc_init; 387 400 ret->close = msn_close; 388 401 ret->send_im = msn_send_im; … … 404 417 ret->rem_deny = msn_rem_deny; 405 418 ret->send_typing = msn_send_typing; 406 ret-> cmp_buddynames= g_strcasecmp;419 ret->handle_cmp = g_strcasecmp; 407 420 408 421 register_protocol(ret); -
protocols/msn/msn.h
rf4aa393 rd8d63a2 157 157 char **msn_linesplit( char *line ); 158 158 int msn_handler( struct msn_handler_data *h ); 159 char *msn_http_encode( const char *input ); 159 160 160 161 /* tables.c */ -
protocols/msn/msn_util.c
rf4aa393 rd8d63a2 54 54 { 55 55 struct msn_data *md = gc->proto_data; 56 GSList *l, **lp = NULL;57 56 char buf[1024], *realname; 58 57 59 if( strcmp( list, "AL" ) == 0 ) 60 lp = &gc->permit; 61 else if( strcmp( list, "BL" ) == 0 ) 62 lp = &gc->deny; 63 64 if( lp ) 65 for( l = *lp; l; l = l->next ) 66 if( g_strcasecmp( l->data, who ) == 0 ) 67 return( 1 ); 68 69 realname = g_new0( char, strlen( realname_ ) * 3 + 1 ); 70 strcpy( realname, realname_ ); 71 http_encode( realname ); 58 realname = msn_http_encode( realname_ ); 72 59 73 60 g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s\r\n", ++md->trId, list, who, realname ); … … 76 63 g_free( realname ); 77 64 78 if( lp )79 *lp = g_slist_append( *lp, g_strdup( who ) );80 81 65 return( 1 ); 82 66 } … … 90 74 { 91 75 struct msn_data *md = gc->proto_data; 92 GSList *l = NULL, **lp = NULL;93 76 char buf[1024]; 94 95 if( strcmp( list, "AL" ) == 0 )96 lp = &gc->permit;97 else if( strcmp( list, "BL" ) == 0 )98 lp = &gc->deny;99 100 if( lp )101 {102 for( l = *lp; l; l = l->next )103 if( g_strcasecmp( l->data, who ) == 0 )104 break;105 106 if( !l )107 return( 1 );108 }109 77 110 78 g_snprintf( buf, sizeof( buf ), "REM %d %s %s\r\n", ++md->trId, list, who ); 111 79 if( msn_write( gc, buf, strlen( buf ) ) ) 112 {113 if( lp )114 *lp = g_slist_remove( *lp, l->data );115 116 80 return( 1 ); 117 }118 81 119 82 return( 0 ); … … 350 313 return( 1 ); 351 314 } 315 316 /* The difference between this function and the normal http_encode() function 317 is that this one escapes every 7-bit ASCII character because this is said 318 to avoid some lame server-side checks when setting a real-name. Also, 319 non-ASCII characters are not escaped because MSN servers don't seem to 320 appreciate that! */ 321 char *msn_http_encode( const char *input ) 322 { 323 char *ret, *s; 324 int i; 325 326 ret = s = g_new0( char, strlen( input ) * 3 + 1 ); 327 for( i = 0; input[i]; i ++ ) 328 if( input[i] & 128 ) 329 { 330 *s = input[i]; 331 s ++; 332 } 333 else 334 { 335 g_snprintf( s, 4, "%%%02X", input[i] ); 336 s += 3; 337 } 338 339 return ret; 340 } -
protocols/msn/ns.c
rf4aa393 rd8d63a2 223 223 else if( num_parts == 7 && strcmp( cmd[2], "OK" ) == 0 ) 224 224 { 225 set_t *s; 226 225 227 http_decode( cmd[4] ); 226 228 227 229 strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) ); 228 230 gc->displayname[sizeof(gc->displayname)-1] = 0; 231 232 if( ( s = set_find( &gc->acc->set, "display_name" ) ) ) 233 { 234 g_free( s->value ); 235 s->value = g_strdup( cmd[4] ); 236 } 229 237 230 238 set_login_progress( gc, 1, "Authenticated, getting buddy list" ); … … 517 525 if( g_strcasecmp( cmd[3], gc->username ) == 0 ) 518 526 { 527 set_t *s; 528 519 529 http_decode( cmd[4] ); 520 530 strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) ); 521 531 gc->displayname[sizeof(gc->displayname)-1] = 0; 532 533 if( ( s = set_find( &gc->acc->set, "display_name" ) ) ) 534 { 535 g_free( s->value ); 536 s->value = g_strdup( cmd[4] ); 537 } 522 538 } 523 539 else -
protocols/msn/passport.c
rf4aa393 rd8d63a2 59 59 rep->data = data; 60 60 rep->func = func; 61 rep->header = header; 61 62 62 63 server = g_strdup( prd_cached ); … … 125 126 static char *passport_create_header( char *cookie, char *email, char *pwd ) 126 127 { 127 char *buffer = g_new0( char, 2048 );128 char *buffer; 128 129 char *currenttoken; 129 130 char *email_enc, *pwd_enc; 131 132 currenttoken = strstr( cookie, "lc=" ); 133 if( currenttoken == NULL ) 134 return NULL; 130 135 131 136 email_enc = g_new0( char, strlen( email ) * 3 + 1 ); … … 137 142 http_encode( pwd_enc ); 138 143 139 currenttoken = strstr( cookie, "lc=" ); 140 if( currenttoken == NULL ) 141 return( NULL ); 142 143 g_snprintf( buffer, 2048, 144 "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 ); 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 148 149 149 g_free( email_enc ); 150 150 g_free( pwd_enc ); 151 151 152 return ( buffer );152 return buffer; 153 153 } 154 154 … … 212 212 if( passport_get_id_real( rep->func, rep->data, rep->header ) ) 213 213 { 214 rep->header = NULL; 214 215 destroy_reply( rep ); 215 216 return; -
protocols/nogaim.c
rf4aa393 rd8d63a2 145 145 /* multi.c */ 146 146 147 struct gaim_connection *new_gaim_conn( struct aim_user *user)147 struct gaim_connection *new_gaim_conn( account_t *acc ) 148 148 { 149 149 struct gaim_connection *gc; 150 account_t *a;151 150 152 151 gc = g_new0( struct gaim_connection, 1 ); 153 152 154 gc->prpl = user->prpl;155 g_snprintf( gc->username, sizeof( gc->username ), "%s", user->username);156 g_snprintf( gc->password, sizeof( gc->password ), "%s", user->password);157 /* [MD] BUGFIX: don't set gc->irc to the global IRC, but use the one from the struct aim_user.158 * This fixes daemon mode breakage where IRC doesn't point to the currently active connection.159 */160 gc->irc = user->irc;153 /* Maybe we should get rid of this memory waste later. ;-) */ 154 g_snprintf( gc->username, sizeof( gc->username ), "%s", acc->user ); 155 g_snprintf( gc->password, sizeof( gc->password ), "%s", acc->pass ); 156 157 gc->irc = acc->irc; 158 gc->acc = acc; 159 acc->gc = gc; 161 160 162 161 connections = g_slist_append( connections, gc ); 163 164 user->gc = gc;165 gc->user = user;166 167 // Find the account_t so we can set its gc pointer168 for( a = gc->irc->accounts; a; a = a->next )169 if( ( struct aim_user * ) a->gc == user )170 {171 a->gc = gc;172 break;173 }174 162 175 163 return( gc ); … … 189 177 190 178 connections = g_slist_remove( connections, gc ); 191 g_free( gc->user );192 179 g_free( gc ); 193 180 } … … 220 207 va_end( params ); 221 208 222 if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||223 ( ( gc->flags & OPT_CONN_HTML ) && set_get int( gc->irc, "strip_html" ) ) )209 if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) || 210 ( ( gc->flags & OPT_CONN_HTML ) && set_getbool( &gc->irc->set, "strip_html" ) ) ) 224 211 strip_html( text ); 225 212 226 213 /* Try to find a different connection on the same protocol. */ 227 214 for( a = gc->irc->accounts; a; a = a->next ) 228 if( a->prpl == gc-> prpl && a->gc != gc )215 if( a->prpl == gc->acc->prpl && a->gc != gc ) 229 216 break; 230 217 231 218 /* If we found one, include the screenname in the message. */ 232 219 if( a ) 233 irc_usermsg( gc->irc, "%s(%s) - %s", gc-> prpl->name, gc->username, text );220 irc_usermsg( gc->irc, "%s(%s) - %s", gc->acc->prpl->name, gc->username, text ); 234 221 else 235 irc_usermsg( gc->irc, "%s - %s", gc-> prpl->name, text );222 irc_usermsg( gc->irc, "%s - %s", gc->acc->prpl->name, text ); 236 223 237 224 g_free( text ); … … 242 229 struct gaim_connection *gc = d; 243 230 244 if( gc-> prpl && gc->prpl->keepalive )245 gc-> prpl->keepalive( gc );231 if( gc->acc->prpl->keepalive ) 232 gc->acc->prpl->keepalive( gc ); 246 233 247 234 return TRUE; … … 297 284 b_event_remove( gc->keepalive ); 298 285 gc->flags |= OPT_LOGGING_OUT; 286 299 287 gc->keepalive = 0; 300 gc-> prpl->close( gc );288 gc->acc->prpl->close( gc ); 301 289 b_event_remove( gc->inpa ); 302 290 … … 323 311 /* Uhm... This is very sick. */ 324 312 } 325 else if( !gc->wants_to_die && set_getint( irc, "auto_reconnect" ) ) 326 { 327 int delay = set_getint( irc, "auto_reconnect_delay" ); 313 else if( !gc->wants_to_die && set_getbool( &irc->set, "auto_reconnect" ) && 314 set_getbool( &a->set, "auto_reconnect" ) ) 315 { 316 int delay = set_getint( &irc->set, "auto_reconnect_delay" ); 328 317 329 318 serv_got_crap( gc, "Reconnecting in %d seconds..", delay ); … … 364 353 irc_t *irc = gc->irc; 365 354 366 if( set_get int( irc, "debug" ) && 0 ) /* This message is too useless */355 if( set_getbool( &irc->set, "debug" ) && 0 ) /* This message is too useless */ 367 356 serv_got_crap( gc, "Receiving user add from handle: %s", handle ); 368 357 369 358 if( user_findhandle( gc, handle ) ) 370 359 { 371 if( set_get int( irc, "debug" ) )360 if( set_getbool( &irc->set, "debug" ) ) 372 361 serv_got_crap( gc, "User already exists, ignoring add request: %s", handle ); 373 362 … … 378 367 379 368 memset( nick, 0, MAX_NICK_LENGTH + 1 ); 380 strcpy( nick, nick_get( gc-> irc, handle, gc->prpl, realname ) );369 strcpy( nick, nick_get( gc->acc, handle, realname ) ); 381 370 382 371 u = user_add( gc->irc, nick ); … … 390 379 u->user = g_strndup( handle, s - handle ); 391 380 } 392 else if( gc-> user->proto_opt[0] && *gc->user->proto_opt[0])381 else if( gc->acc->server ) 393 382 { 394 383 char *colon; 395 384 396 if( ( colon = strchr( gc-> user->proto_opt[0], ':' ) ) )397 u->host = g_strndup( gc-> user->proto_opt[0],398 colon - gc-> user->proto_opt[0]);385 if( ( colon = strchr( gc->acc->server, ':' ) ) ) 386 u->host = g_strndup( gc->acc->server, 387 colon - gc->acc->server ); 399 388 else 400 u->host = g_strdup( gc-> user->proto_opt[0]);389 u->host = g_strdup( gc->acc->server ); 401 390 402 391 u->user = g_strdup( handle ); … … 409 398 else 410 399 { 411 u->host = g_strdup( gc-> user->prpl->name );400 u->host = g_strdup( gc->acc->prpl->name ); 412 401 u->user = g_strdup( handle ); 413 402 } … … 457 446 u->realname = g_strdup( realname ); 458 447 459 if( ( gc->flags & OPT_LOGGED_IN ) && set_get int( gc->irc, "display_namechanges" ) )448 if( ( gc->flags & OPT_LOGGED_IN ) && set_getbool( &gc->irc->set, "display_namechanges" ) ) 460 449 serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname ); 461 450 } … … 479 468 void show_got_added_yes( gpointer w, struct show_got_added_data *data ) 480 469 { 481 data->gc-> prpl->add_buddy( data->gc, data->handle );470 data->gc->acc->prpl->add_buddy( data->gc, data->handle ); 482 471 add_buddy( data->gc, NULL, data->handle, data->handle ); 483 472 … … 513 502 if( !u ) 514 503 { 515 if( g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "add" ) == 0 )504 if( g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "add" ) == 0 ) 516 505 { 517 506 add_buddy( gc, NULL, handle, NULL ); … … 520 509 else 521 510 { 522 if( set_get int( gc->irc, "debug" ) || g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "ignore" ) != 0 )511 if( set_getbool( &gc->irc->set, "debug" ) || g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "ignore" ) != 0 ) 523 512 { 524 513 serv_got_crap( gc, "serv_got_update() for handle %s:", handle ); … … 558 547 } 559 548 560 if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "oscar") || !strcmp(gc->prpl->name, "icq")) )549 if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "oscar" ) == 0 || strcmp( gc->acc->prpl->name, "icq" ) == 0 ) ) 561 550 { 562 551 u->away = g_strdup( "Away" ); 563 552 } 564 else if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "jabber")) )553 else if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "jabber" ) == 0 ) ) 565 554 { 566 555 if( type & UC_DND ) … … 571 560 u->away = g_strdup( "Away" ); 572 561 } 573 else if( ( type & UC_UNAVAILABLE ) && gc-> prpl->get_status_string )574 { 575 u->away = g_strdup( gc-> prpl->get_status_string( gc, type ) );562 else if( ( type & UC_UNAVAILABLE ) && gc->acc->prpl->get_status_string ) 563 { 564 u->away = g_strdup( gc->acc->prpl->get_status_string( gc, type ) ); 576 565 } 577 566 else … … 579 568 580 569 /* LISPy... */ 581 if( ( set_get int( gc->irc, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */570 if( ( set_getbool( &gc->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ 582 571 ( u->online ) && /* Don't touch offline people */ 583 572 ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ 584 573 ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ 585 574 { 586 irc_write( gc->irc, ":%s !%s@%s MODE %s %cv %s", gc->irc->mynick, gc->irc->mynick, gc->irc->myhost,575 irc_write( gc->irc, ":%s MODE %s %cv %s", gc->irc->myhost, 587 576 gc->irc->channel, u->away?'-':'+', u->nick ); 588 577 } … … 598 587 if( !u ) 599 588 { 600 char *h = set_getstr( irc, "handle_unknown" );589 char *h = set_getstr( &irc->set, "handle_unknown" ); 601 590 602 591 if( g_strcasecmp( h, "ignore" ) == 0 ) 603 592 { 604 if( set_get int( irc, "debug" ) )593 if( set_getbool( &irc->set, "debug" ) ) 605 594 serv_got_crap( gc, "Ignoring message from unknown handle %s", handle ); 606 595 … … 609 598 else if( g_strncasecmp( h, "add", 3 ) == 0 ) 610 599 { 611 int private = set_get int( irc, "private" );600 int private = set_getbool( &irc->set, "private" ); 612 601 613 602 if( h[3] ) … … 630 619 } 631 620 632 if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||633 ( ( gc->flags & OPT_CONN_HTML ) && set_get int( gc->irc, "strip_html" ) ) )621 if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) || 622 ( ( gc->flags & OPT_CONN_HTML ) && set_getbool( &gc->irc->set, "strip_html" ) ) ) 634 623 strip_html( msg ); 635 624 … … 671 660 user_t *u; 672 661 673 if( !set_get int( gc->irc, "typing_notice" ) )662 if( !set_getbool( &gc->irc->set, "typing_notice" ) ) 674 663 return; 675 664 … … 693 682 GList *ir; 694 683 695 if( set_get int( gc->irc, "debug" ) )684 if( set_getbool( &gc->irc->set, "debug" ) ) 696 685 serv_got_crap( gc, "You were removed from conversation %d", (int) id ); 697 686 … … 732 721 733 722 /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ 734 if( g_strcasecmp( who, gc->user ->username ) == 0 )723 if( g_strcasecmp( who, gc->username ) == 0 ) 735 724 return; 736 725 … … 738 727 for( c = gc->conversations; c && c->id != id; c = c->next ); 739 728 740 if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||741 ( ( gc->flags & OPT_CONN_HTML ) && set_get int( gc->irc, "strip_html" ) ) )729 if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) || 730 ( ( gc->flags & OPT_CONN_HTML ) && set_getbool( &gc->irc->set, "strip_html" ) ) ) 742 731 strip_html( msg ); 743 732 … … 772 761 g_free( s ); 773 762 774 if( set_get int( gc->irc, "debug" ) )763 if( set_getbool( &gc->irc->set, "debug" ) ) 775 764 serv_got_crap( gc, "Creating new conversation: (id=%d,handle=%s)", id, handle ); 776 765 … … 786 775 int me = 0; 787 776 788 if( set_get int( b->gc->irc, "debug" ) )777 if( set_getbool( &b->gc->irc->set, "debug" ) ) 789 778 serv_got_crap( b->gc, "User %s added to conversation %d", handle, b->id ); 790 779 791 780 /* It might be yourself! */ 792 if( b->gc-> prpl->cmp_buddynames( handle, b->gc->user->username ) == 0 )781 if( b->gc->acc->prpl->handle_cmp( handle, b->gc->username ) == 0 ) 793 782 { 794 783 u = user_find( b->gc->irc, b->gc->irc->nick ); … … 820 809 int me = 0; 821 810 822 if( set_get int( b->gc->irc, "debug" ) )811 if( set_getbool( &b->gc->irc->set, "debug" ) ) 823 812 serv_got_crap( b->gc, "User %s removed from conversation %d (%s)", handle, b->id, reason ? reason : "" ); 824 813 825 814 /* It might be yourself! */ 826 if( g_strcasecmp( handle, b->gc->user ->username ) == 0 )815 if( g_strcasecmp( handle, b->gc->username ) == 0 ) 827 816 { 828 817 u = user_find( b->gc->irc, b->gc->irc->nick ); … … 882 871 } 883 872 884 char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ) 885 { 873 char *set_eval_away_devoice( set_t *set, char *value ) 874 { 875 irc_t *irc = set->data; 886 876 int st; 887 877 … … 897 887 /* Horror.... */ 898 888 899 if( st != set_get int( irc, "away_devoice" ) )889 if( st != set_getbool( &irc->set, "away_devoice" ) ) 900 890 { 901 891 char list[80] = ""; … … 917 907 { 918 908 for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0; 919 irc_write( irc, ":%s !%s@%sMODE %s %c%s%s",920 irc->my nick, irc->mynick, irc->myhost,909 irc_write( irc, ":%s MODE %s %c%s%s", 910 irc->myhost, 921 911 irc->channel, pm, v, list ); 922 912 … … 933 923 /* $v = 'v' x $i */ 934 924 for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0; 935 irc_write( irc, ":%s !%s@%s MODE %s %c%s%s", irc->mynick, irc->mynick, irc->myhost,925 irc_write( irc, ":%s MODE %s %c%s%s", irc->myhost, 936 926 irc->channel, pm, v, list ); 937 927 } 938 928 939 return( set_eval_bool( irc,set, value ) );929 return( set_eval_bool( set, value ) ); 940 930 } 941 931 … … 957 947 } 958 948 959 st = gc-> prpl->send_im( gc, handle, msg, strlen( msg ), flags );949 st = gc->acc->prpl->send_im( gc, handle, msg, strlen( msg ), flags ); 960 950 g_free( buf ); 961 951 … … 974 964 } 975 965 976 st = gc-> prpl->chat_send( gc, id, msg );966 st = gc->acc->prpl->chat_send( gc, id, msg ); 977 967 g_free( buf ); 978 968 … … 988 978 989 979 if( !away ) away = ""; 990 ms = m = gc-> prpl->away_states( gc );980 ms = m = gc->acc->prpl->away_states( gc ); 991 981 992 982 while( m ) … … 1009 999 if( m ) 1010 1000 { 1011 gc-> prpl->set_away( gc, m->data, *away ? away : NULL );1001 gc->acc->prpl->set_away( gc, m->data, *away ? away : NULL ); 1012 1002 } 1013 1003 else … … 1016 1006 if( s ) 1017 1007 { 1018 gc-> prpl->set_away( gc, s, away );1019 if( set_get int( gc->irc, "debug" ) )1008 gc->acc->prpl->set_away( gc, s, away ); 1009 if( set_getbool( &gc->irc->set, "debug" ) ) 1020 1010 serv_got_crap( gc, "Setting away state to %s", s ); 1021 1011 } 1022 1012 else 1023 gc-> prpl->set_away( gc, GAIM_AWAY_CUSTOM, away );1013 gc->acc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); 1024 1014 } 1025 1015 … … 1073 1063 void bim_add_allow( struct gaim_connection *gc, char *handle ) 1074 1064 { 1075 if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc-> prpl->cmp_buddynames) == NULL )1065 if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL ) 1076 1066 { 1077 1067 gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) ); 1078 1068 } 1079 1069 1080 gc-> prpl->add_permit( gc, handle );1070 gc->acc->prpl->add_permit( gc, handle ); 1081 1071 } 1082 1072 … … 1085 1075 GSList *l; 1086 1076 1087 if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc-> prpl->cmp_buddynames) ) )1077 if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) ) 1088 1078 { 1089 1079 g_free( l->data ); … … 1091 1081 } 1092 1082 1093 gc-> prpl->rem_permit( gc, handle );1083 gc->acc->prpl->rem_permit( gc, handle ); 1094 1084 } 1095 1085 1096 1086 void bim_add_block( struct gaim_connection *gc, char *handle ) 1097 1087 { 1098 if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc-> prpl->cmp_buddynames) == NULL )1088 if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL ) 1099 1089 { 1100 1090 gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) ); 1101 1091 } 1102 1092 1103 gc-> prpl->add_deny( gc, handle );1093 gc->acc->prpl->add_deny( gc, handle ); 1104 1094 } 1105 1095 … … 1108 1098 GSList *l; 1109 1099 1110 if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc-> prpl->cmp_buddynames) ) )1100 if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) ) 1111 1101 { 1112 1102 g_free( l->data ); … … 1114 1104 } 1115 1105 1116 gc-> prpl->rem_deny( gc, handle );1117 } 1106 gc->acc->prpl->rem_deny( gc, handle ); 1107 } -
protocols/nogaim.h
rf4aa393 rd8d63a2 39 39 40 40 #include "bitlbee.h" 41 #include "account.h" 41 42 #include "proxy.h" 42 43 #include "md5.h" … … 63 64 struct gaim_connection 64 65 { 65 struct prpl *prpl;66 account_t *acc; 66 67 guint32 flags; 67 68 … … 78 79 GSList *deny; 79 80 int permdeny; 80 81 struct aim_user *user;82 81 83 82 char username[64]; … … 126 125 }; 127 126 128 struct aim_user {129 char username[64];130 char alias[SELF_ALIAS_LEN];131 char password[32];132 char user_info[2048];133 int options;134 struct prpl *prpl;135 /* prpls can use this to save information about the user,136 * like which server to connect to, etc */137 char proto_opt[7][256];138 139 struct gaim_connection *gc;140 irc_t *irc;141 };142 143 127 struct prpl { 144 128 int options; 145 129 const char *name; 146 130 147 void (* login) (struct aim_user *); 131 void (* acc_init) (account_t *); 132 void (* login) (account_t *); 148 133 void (* keepalive) (struct gaim_connection *); 149 134 void (* close) (struct gaim_connection *); … … 180 165 181 166 /* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* */ 182 int (* cmp_buddynames) (const char *who1, const char *who2);167 int (* handle_cmp) (const char *who1, const char *who2); 183 168 }; 184 169 … … 206 191 207 192 void nogaim_init(); 208 char *set_eval_away_devoice( irc_t *irc,set_t *set, char *value );193 char *set_eval_away_devoice( set_t *set, char *value ); 209 194 210 195 gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ); … … 212 197 213 198 /* multi.c */ 214 G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( struct aim_user *user);199 G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( account_t *acc ); 215 200 G_MODULE_EXPORT void destroy_gaim_conn( struct gaim_connection *gc ); 216 201 G_MODULE_EXPORT void set_login_progress( struct gaim_connection *gc, int step, char *msg ); -
protocols/oscar/info.c
rf4aa393 rd8d63a2 261 261 if (!identified) { 262 262 /*FIXME*/ 263 /*REMOVEME :-) 263 264 g_strdup_printf("unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", 264 265 cap[0], cap[1], cap[2], cap[3], … … 268 269 cap[10], cap[11], cap[12], cap[13], 269 270 cap[14], cap[15]); 270 271 */ 271 272 } 272 273 -
protocols/oscar/oscar.c
rf4aa393 rd8d63a2 356 356 } 357 357 358 static void oscar_login(struct aim_user *user) { 358 static void oscar_acc_init(account_t *acc) 359 { 360 set_t *s; 361 362 s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); 363 s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; 364 365 if (isdigit(acc->user[0])) { 366 s = set_add( &acc->set, "web_aware", "false", set_eval_bool, acc ); 367 s->flags |= ACC_SET_OFFLINE_ONLY; 368 } 369 } 370 371 static void oscar_login(account_t *acc) { 359 372 aim_session_t *sess; 360 373 aim_conn_t *conn; 361 374 char buf[256]; 362 struct gaim_connection *gc = new_gaim_conn( user);375 struct gaim_connection *gc = new_gaim_conn(acc); 363 376 struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1); 364 377 365 if (isdigit( *user->username)) {378 if (isdigit(acc->user[0])) { 366 379 odata->icq = TRUE; 367 380 /* This is odd but it's necessary for a proper do_import and do_export. 368 381 We don't do those anymore, but let's stick with it, just in case 369 it accidentally fixes something else too... */382 it accidentally fixes something else too... </bitlbee> */ 370 383 gc->password[8] = 0; 371 384 } else { … … 390 403 } 391 404 392 if (g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.icq.com") != 0 && 393 g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.oscar.aol.com") != 0) { 394 serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",user->proto_opt[USEROPT_AUTH]); 405 if (acc->server == NULL) { 406 hide_login_progress(gc, "No servername specified"); 407 signoff(gc); 408 return; 409 } 410 411 if (g_strcasecmp(acc->server, "login.icq.com") != 0 && 412 g_strcasecmp(acc->server, "login.oscar.aol.com") != 0) { 413 serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",acc->server); 395 414 } 396 415 … … 402 421 403 422 conn->status |= AIM_CONN_STATUS_INPROGRESS; 404 conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ? 405 user->proto_opt[USEROPT_AUTH] : AIM_DEFAULT_LOGIN_SERVER, 406 user->proto_opt[USEROPT_AUTHPORT][0] ? 407 atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT, 408 oscar_login_connect, gc); 423 conn->fd = proxy_connect(acc->server, AIM_LOGIN_PORT, oscar_login_connect, gc); 409 424 if (conn->fd < 0) { 410 425 hide_login_progress(gc, _("Couldn't connect to host")); … … 485 500 struct aim_authresp_info *info; 486 501 int i; char *host; int port; 487 struct aim_user *user;488 502 aim_conn_t *bosconn; 489 503 490 504 struct gaim_connection *gc = sess->aux_data; 491 505 struct oscar_data *od = gc->proto_data; 492 user = gc->user; 493 port = user->proto_opt[USEROPT_AUTHPORT][0] ? 494 atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT, 506 port = AIM_LOGIN_PORT; 495 507 496 508 va_start(ap, fr); … … 871 883 struct aim_redirect_data *redir; 872 884 struct gaim_connection *gc = sess->aux_data; 873 struct aim_user *user = gc->user;874 885 aim_conn_t *tstconn; 875 886 int i; … … 877 888 int port; 878 889 879 port = user->proto_opt[USEROPT_AUTHPORT][0] ?880 atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,881 882 890 va_start(ap, fr); 883 891 redir = va_arg(ap, struct aim_redirect_data *); 884 892 va_end(ap); 885 893 894 port = AIM_LOGIN_PORT; 886 895 for (i = 0; i < (int)strlen(redir->ip); i++) { 887 896 if (redir->ip[i] == ':') { … … 1242 1251 channel = va_arg(ap, int); 1243 1252 userinfo = va_arg(ap, aim_userinfo_t *); 1244 1245 if (set_getint(sess->aux_data, "debug")) {1246 serv_got_crap(sess->aux_data, "channel %i called", channel);1247 }1248 1253 1249 1254 switch (channel) { … … 1723 1728 odata->rights.maxsiglen = odata->rights.maxawaymsglen = (guint)maxsiglen; 1724 1729 1730 /* FIXME: It seems we're not really using this, and it broke now that 1731 struct aim_user is dead. 1725 1732 aim_bos_setprofile(sess, fr->conn, gc->user->user_info, NULL, gaim_caps); 1726 1733 */ 1734 1727 1735 return 1; 1728 1736 } … … 2289 2297 } 2290 2298 info_string_append(str, "\n", _("Mobile Phone"), info->mobile); 2291 info_string_append(str, "\n", _("Gender"), info->gender==1 ? _("Female") : _("Male"));2299 info_string_append(str, "\n", _("Gender"), info->gender==1 ? _("Female") : info->gender==2 ? _("Male") : _("Unknown")); 2292 2300 if (info->birthyear || info->birthmonth || info->birthday) { 2293 2301 char date[30]; … … 2656 2664 ret->away_states = oscar_away_states; 2657 2665 ret->login = oscar_login; 2666 ret->acc_init = oscar_acc_init; 2658 2667 ret->close = oscar_close; 2659 2668 ret->send_im = oscar_send_im; … … 2673 2682 ret->set_permit_deny = oscar_set_permit_deny; 2674 2683 ret->keepalive = oscar_keepalive; 2675 ret->cmp_buddynames = aim_sncmp;2676 2684 ret->get_status_string = oscar_get_status_string; 2677 2685 ret->send_typing = oscar_send_typing; 2686 2687 ret->handle_cmp = aim_sncmp; 2678 2688 2679 2689 register_protocol(ret); -
protocols/oscar/rxhandlers.c
rf4aa393 rd8d63a2 112 112 /* Following SNAC will be related */ 113 113 } 114 115 if (set_getint(sess->aux_data, "debug")) {116 serv_got_crap(sess->aux_data, "snac %x/%x received", snac.family, snac.subtype);117 }118 114 119 115 for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) { -
protocols/oscar/service.c
rf4aa393 rd8d63a2 732 732 guint32 data; 733 733 int tlvlen; 734 struct gaim_connection *gc = sess ? sess->aux_data : NULL; 734 735 735 736 data = AIM_ICQ_STATE_HIDEIP | status; /* yay for error checking ;^) */ 737 738 if (gc && set_getbool(&gc->acc->set, "web_aware")) 739 data |= AIM_ICQ_STATE_WEBAWARE; 736 740 737 741 tlvlen = aim_addtlvtochain32(&tl, 0x0006, data); -
protocols/yahoo/libyahoo2.c
rf4aa393 rd8d63a2 89 89 #define vsnprintf _vsnprintf 90 90 #endif 91 92 #include "base64.h" 91 93 92 94 #ifdef USE_STRUCT_CALLBACKS … … 695 697 } 696 698 697 static char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 698 "abcdefghijklmnopqrstuvwxyz" 699 "0123456789._"; 699 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ 700 700 static void to_y64(unsigned char *out, const unsigned char *in, int inlen) 701 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ 702 { 703 for (; inlen >= 3; inlen -= 3) 704 { 705 *out++ = base64digits[in[0] >> 2]; 706 *out++ = base64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; 707 *out++ = base64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)]; 708 *out++ = base64digits[in[2] & 0x3f]; 709 in += 3; 710 } 711 if (inlen > 0) 712 { 713 unsigned char fragment; 714 715 *out++ = base64digits[in[0] >> 2]; 716 fragment = (in[0] << 4) & 0x30; 717 if (inlen > 1) 718 fragment |= in[1] >> 4; 719 *out++ = base64digits[fragment]; 720 *out++ = (inlen < 2) ? '-' 721 : base64digits[(in[1] << 2) & 0x3c]; 722 *out++ = '-'; 723 } 724 *out = '\0'; 701 { 702 base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); 725 703 } 726 704 -
protocols/yahoo/yahoo.c
rf4aa393 rd8d63a2 121 121 } 122 122 123 static void byahoo_login( struct aim_user *user)124 { 125 struct gaim_connection *gc = new_gaim_conn( user);123 static void byahoo_login( account_t *acc ) 124 { 125 struct gaim_connection *gc = new_gaim_conn( acc ); 126 126 struct byahoo_data *yd = gc->proto_data = g_new0( struct byahoo_data, 1 ); 127 127 … … 130 130 131 131 set_login_progress( gc, 1, "Connecting" ); 132 yd->y2_id = yahoo_init( user->username, user->password);132 yd->y2_id = yahoo_init( acc->user, acc->pass ); 133 133 yahoo_login( yd->y2_id, yd->current_status ); 134 134 } … … 192 192 gc->away = NULL; 193 193 194 if( msg)194 if( state && msg && g_strcasecmp( state, msg ) != 0 ) 195 195 { 196 196 yd->current_status = YAHOO_STATUS_CUSTOM; 197 197 gc->away = ""; 198 198 } 199 if( state ) 200 { 199 else if( state ) 200 { 201 /* Set msg to NULL since (if it isn't NULL already) it's equal 202 to state. msg must be empty if we want to use an existing 203 away state. */ 204 msg = NULL; 205 201 206 gc->away = ""; 202 207 if( g_strcasecmp( state, "Available" ) == 0 ) … … 235 240 yd->current_status = YAHOO_STATUS_AVAILABLE; 236 241 237 if( yd->current_status == YAHOO_STATUS_INVISIBLE ) 238 yahoo_set_away( yd->y2_id, yd->current_status, NULL, gc->away != NULL ); 239 else 240 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL ); 242 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL ); 241 243 } 242 244 … … 409 411 ret->chat_leave = byahoo_chat_leave; 410 412 ret->chat_open = byahoo_chat_open; 411 ret->cmp_buddynames = g_strcasecmp; 413 414 ret->handle_cmp = g_strcasecmp; 412 415 413 416 register_protocol(ret); … … 425 428 yd = gc->proto_data; 426 429 427 if( !strcmp(gc->prpl->name, "yahoo")&& yd->y2_id == id )430 if( strcmp( gc->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id ) 428 431 return( gc ); 429 432 } -
query.c
rf4aa393 rd8d63a2 63 63 } 64 64 65 if( g_strcasecmp( set_getstr( irc, "query_order" ), "lifo" ) == 0 || irc->queries == q )65 if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "lifo" ) == 0 || irc->queries == q ) 66 66 query_display( irc, q ); 67 67 … … 172 172 query_t *q; 173 173 174 if( g_strcasecmp( set_getstr( irc, "query_order" ), "fifo" ) == 0 )174 if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "fifo" ) == 0 ) 175 175 q = irc->queries; 176 176 else -
root_commands.c
rf4aa393 rd8d63a2 127 127 } 128 128 129 static void cmd_account( irc_t *irc, char **cmd ); 130 129 131 static void cmd_identify( irc_t *irc, char **cmd ) 130 132 { 131 133 storage_status_t status = storage_load( irc->nick, cmd[1], irc ); 134 char *account_on[] = { "account", "on", NULL }; 132 135 133 136 switch (status) { … … 139 142 break; 140 143 case STORAGE_OK: 141 irc_usermsg( irc, "Password accepted " );144 irc_usermsg( irc, "Password accepted, settings and accounts loaded" ); 142 145 irc_umode_set( irc, "+R", 1 ); 146 if( set_getbool( &irc->set, "auto_connect" ) ) 147 cmd_account( irc, account_on ); 143 148 break; 149 case STORAGE_OTHER_ERROR: 144 150 default: 145 irc_usermsg( irc, " Something very weird happened" );151 irc_usermsg( irc, "Unknown error while loading configuration" ); 146 152 break; 147 153 } … … 163 169 164 170 case STORAGE_OK: 171 irc_usermsg( irc, "Account successfully created" ); 165 172 irc->status |= USTATUS_IDENTIFIED; 166 173 irc_umode_set( irc, "+R", 1 ); … … 226 233 227 234 a = account_add( irc, prpl, cmd[3], cmd[4] ); 228 229 235 if( cmd[5] ) 230 a->server = g_strdup(cmd[5] );236 set_setstr( &a->set, "server", cmd[5] ); 231 237 232 238 irc_usermsg( irc, "Account successfully added" ); … … 306 312 307 313 for( a = irc->accounts; a; a = a->next ) 308 if( !a->gc )314 if( !a->gc && a->auto_connect ) 309 315 account_on( irc, a ); 310 316 } … … 352 358 } 353 359 } 360 else if( g_strcasecmp( cmd[1], "set" ) == 0 ) 361 { 362 char *acc_handle, *set_name = NULL, *tmp; 363 364 if( !cmd[2] ) 365 { 366 irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); 367 return; 368 } 369 370 acc_handle = g_strdup( cmd[2] ); 371 if( ( tmp = strchr( acc_handle, '/' ) ) ) 372 { 373 *tmp = 0; 374 set_name = tmp + 1; 375 } 376 a = account_get( irc, acc_handle ); 377 378 if( a == NULL ) 379 { 380 g_free( acc_handle ); 381 irc_usermsg( irc, "Invalid account" ); 382 return; 383 } 384 385 if( cmd[3] ) 386 { 387 set_t *s = set_find( &a->set, set_name ); 388 389 if( a->gc && s && s->flags & ACC_SET_OFFLINE_ONLY ) 390 { 391 g_free( acc_handle ); 392 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); 393 return; 394 } 395 else if( !a->gc && s && s->flags & ACC_SET_ONLINE_ONLY ) 396 { 397 g_free( acc_handle ); 398 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); 399 return; 400 } 401 402 set_setstr( &a->set, set_name, cmd[3] ); 403 404 if( ( strcmp( cmd[3], "=" ) ) == 0 && cmd[4] ) 405 irc_usermsg( irc, "Warning: Correct syntax: \002account set <variable> <value>\002 (without =)" ); 406 } 407 if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ 408 { 409 char *s = set_getstr( &a->set, set_name ); 410 if( s ) 411 irc_usermsg( irc, "%s = `%s'", set_name, s ); 412 else 413 irc_usermsg( irc, "%s is empty", set_name ); 414 } 415 else 416 { 417 set_t *s = a->set; 418 while( s ) 419 { 420 if( s->value || s->def ) 421 irc_usermsg( irc, "%s = `%s'", s->key, s->value?s->value:s->def ); 422 else 423 irc_usermsg( irc, "%s is empty", s->key ); 424 s = s->next; 425 } 426 } 427 428 g_free( acc_handle ); 429 } 354 430 else 355 431 { … … 394 470 else 395 471 { 396 nick_set( irc, cmd[2], a->gc->prpl, cmd[3] );472 nick_set( a, cmd[2], cmd[3] ); 397 473 } 398 474 } … … 401 477 add them to your *real* (server-side) contact list. */ 402 478 if( add_for_real ) 403 a->gc-> prpl->add_buddy( a->gc, cmd[2] );479 a->gc->acc->prpl->add_buddy( a->gc, cmd[2] ); 404 480 405 481 add_buddy( a->gc, NULL, cmd[2], cmd[2] ); … … 435 511 } 436 512 437 if( !gc-> prpl->get_info )513 if( !gc->acc->prpl->get_info ) 438 514 { 439 515 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); … … 441 517 else 442 518 { 443 gc-> prpl->get_info( gc, cmd[2] );519 gc->acc->prpl->get_info( gc, cmd[2] ); 444 520 } 445 521 } … … 476 552 else if( u->send_handler == buddy_send_handler ) 477 553 { 478 nick_set( irc, u->handle, u->gc->prpl, cmd[2] );554 nick_set( u->gc->acc, u->handle, cmd[2] ); 479 555 } 480 556 … … 495 571 s = g_strdup( u->handle ); 496 572 497 u->gc-> prpl->remove_buddy( u->gc, u->handle, NULL );573 u->gc->acc->prpl->remove_buddy( u->gc, u->handle, NULL ); 498 574 user_del( irc, cmd[1] ); 499 nick_del( irc, cmd[1]);575 nick_del( u->gc->acc, s ); 500 576 501 577 irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] ); … … 552 628 } 553 629 554 if( !gc-> prpl->add_deny || !gc->prpl->rem_permit )630 if( !gc->acc->prpl->add_deny || !gc->acc->prpl->rem_permit ) 555 631 { 556 632 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); … … 580 656 581 657 irc_usermsg( irc, format, "Handle", "Nickname" ); 582 for( l = a->gc-> deny; l; l = l->next )658 for( l = a->gc->permit; l; l = l->next ) 583 659 { 584 660 user_t *u = user_findhandle( a->gc, l->data ); … … 611 687 } 612 688 613 if( !gc-> prpl->rem_deny || !gc->prpl->add_permit )689 if( !gc->acc->prpl->rem_deny || !gc->acc->prpl->add_permit ) 614 690 { 615 691 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); … … 666 742 if( cmd[1] && cmd[2] ) 667 743 { 668 set_setstr( irc, cmd[1], cmd[2] );744 set_setstr( &irc->set, cmd[1], cmd[2] ); 669 745 670 746 if( ( strcmp( cmd[2], "=" ) ) == 0 && cmd[3] ) … … 673 749 if( cmd[1] ) /* else 'forgotten' on purpose.. Must show new value after changing */ 674 750 { 675 char *s = set_getstr( irc, cmd[1] );751 char *s = set_getstr( &irc->set, cmd[1] ); 676 752 if( s ) 677 753 irc_usermsg( irc, "%s = `%s'", cmd[1], s ); 754 else 755 irc_usermsg( irc, "%s is empty", cmd[1] ); 678 756 } 679 757 else … … 684 762 if( s->value || s->def ) 685 763 irc_usermsg( irc, "%s = `%s'", s->key, s->value?s->value:s->def ); 764 else 765 irc_usermsg( irc, "%s is empty", s->key ); 686 766 s = s->next; 687 767 } … … 727 807 if( online == 1 ) 728 808 { 729 g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc-> user->prpl->name );809 g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name ); 730 810 irc_usermsg( irc, format, u->nick, s, "Online" ); 731 811 } … … 738 818 if( away == 1 ) 739 819 { 740 g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc-> user->prpl->name );820 g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name ); 741 821 irc_usermsg( irc, format, u->nick, s, u->away ); 742 822 } … … 748 828 if( offline == 1 ) 749 829 { 750 g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc-> user->prpl->name );830 g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name ); 751 831 irc_usermsg( irc, format, u->nick, s, "Offline" ); 752 832 } … … 773 853 irc_usermsg( irc, "Your name is `%s'" , a->gc->displayname ? a->gc->displayname : "NULL" ); 774 854 } 775 else if ( !a-> gc->prpl->set_info )855 else if ( !a->prpl->set_info ) 776 856 { 777 857 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); … … 781 861 irc_usermsg( irc, "Setting your name to `%s'", cmd[2] ); 782 862 783 a-> gc->prpl->set_info( a->gc, cmd[2] );863 a->prpl->set_info( a->gc, cmd[2] ); 784 864 } 785 865 } … … 800 880 for( num = 0; q; q = q->next, num ++ ) 801 881 if( q->gc ) /* Not necessary yet, but it might come later */ 802 irc_usermsg( irc, "%d, %s(%s): %s", num, q->gc-> prpl->name, q->gc->username, q->question );882 irc_usermsg( irc, "%d, %s(%s): %s", num, q->gc->acc->prpl->name, q->gc->username, q->question ); 803 883 else 804 884 irc_usermsg( irc, "%d, BitlBee: %s", num, q->question ); 805 }806 807 static void cmd_import_buddies( irc_t *irc, char **cmd )808 {809 struct gaim_connection *gc;810 account_t *a;811 nick_t *n;812 813 if( !( a = account_get( irc, cmd[1] ) ) )814 {815 irc_usermsg( irc, "Invalid account" );816 return;817 }818 else if( !( ( gc = a->gc ) && ( a->gc->flags & OPT_LOGGED_IN ) ) )819 {820 irc_usermsg( irc, "That account is not on-line" );821 return;822 }823 824 if( cmd[2] )825 {826 if( g_strcasecmp( cmd[2], "clear" ) == 0 )827 {828 user_t *u;829 830 for( u = irc->users; u; u = u->next )831 if( u->gc == gc )832 {833 u->gc->prpl->remove_buddy( u->gc, u->handle, NULL );834 user_del( irc, u->nick );835 }836 837 irc_usermsg( irc, "Old buddy list cleared." );838 }839 else840 {841 irc_usermsg( irc, "Invalid argument: %s", cmd[2] );842 return;843 }844 }845 846 for( n = gc->irc->nicks; n; n = n->next )847 {848 if( n->proto == gc->prpl && !user_findhandle( gc, n->handle ) )849 {850 gc->prpl->add_buddy( gc, n->handle );851 add_buddy( gc, NULL, n->handle, NULL );852 }853 }854 855 irc_usermsg( irc, "Sent all add requests. Please wait for a while, the server needs some time to handle all the adds." );856 885 } 857 886 … … 874 903 { "blist", 0, cmd_blist, 0 }, 875 904 { "nick", 1, cmd_nick, 0 }, 876 { "import_buddies", 1, cmd_import_buddies, 0 },877 905 { "qlist", 0, cmd_qlist, 0 }, 878 906 { NULL } -
set.c
rf4aa393 rd8d63a2 26 26 #include "bitlbee.h" 27 27 28 set_t *set_add( irc_t *irc, char *key, char *def, void *eval ) 29 { 30 set_t *s = set_find( irc, key ); 31 32 if( !s ) 33 { 34 if( ( s = irc->set ) ) 28 set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ) 29 { 30 set_t *s = set_find( head, key ); 31 32 /* Possibly the setting already exists. If it doesn't exist yet, 33 we create it. If it does, we'll just change the default. */ 34 if( !s ) 35 { 36 if( ( s = *head ) ) 35 37 { 36 38 while( s->next ) s = s->next; 37 s->next = g_new 39 s->next = g_new0( set_t, 1 ); 38 40 s = s->next; 39 41 } 40 42 else 41 43 { 42 s = irc->set = g_new( set_t, 1 );44 s = *head = g_new0( set_t, 1 ); 43 45 } 44 memset( s, 0, sizeof( set_t ) );45 46 s->key = g_strdup( key ); 46 47 } … … 53 54 if( def ) s->def = g_strdup( def ); 54 55 55 if( s->eval ) 56 { 57 g_free( s->eval ); 58 s->eval = NULL; 59 } 60 if( eval ) s->eval = eval; 61 62 return( s ); 63 } 64 65 set_t *set_find( irc_t *irc, char *key ) 66 { 67 set_t *s = irc->set; 56 s->eval = eval; 57 s->data = data; 58 59 return s; 60 } 61 62 set_t *set_find( set_t **head, char *key ) 63 { 64 set_t *s = *head; 68 65 69 66 while( s ) … … 74 71 } 75 72 76 return ( s );77 } 78 79 char *set_getstr( irc_t *irc, char *key )80 { 81 set_t *s = set_find( irc, key );73 return s; 74 } 75 76 char *set_getstr( set_t **head, char *key ) 77 { 78 set_t *s = set_find( head, key ); 82 79 83 80 if( !s || ( !s->value && !s->def ) ) 84 return ( NULL );85 86 return ( s->value?s->value:s->def );87 } 88 89 int set_getint( irc_t *irc, char *key )90 { 91 char *s = set_getstr( irc, key );81 return NULL; 82 83 return s->value ? s->value : s->def; 84 } 85 86 int set_getint( set_t **head, char *key ) 87 { 88 char *s = set_getstr( head, key ); 92 89 int i = 0; 93 90 94 91 if( !s ) 95 return ( 0 );92 return 0; 96 93 97 94 if( ( g_strcasecmp( s, "true" ) == 0 ) || ( g_strcasecmp( s, "yes" ) == 0 ) || ( g_strcasecmp( s, "on" ) == 0 ) ) 98 return ( 1 );95 return 1; 99 96 100 97 if( sscanf( s, "%d", &i ) != 1 ) 101 return( 0 ); 102 103 return( i ); 104 } 105 106 int set_setstr( irc_t *irc, char *key, char *value ) 107 { 108 set_t *s = set_find( irc, key ); 98 return 0; 99 100 return i; 101 } 102 103 int set_getbool( set_t **head, char *key ) 104 { 105 char *s = set_getstr( head, key ); 106 107 if( !s ) 108 return 0; 109 110 return bool2int( s ); 111 } 112 113 int set_setstr( set_t **head, char *key, char *value ) 114 { 115 set_t *s = set_find( head, key ); 109 116 char *nv = value; 110 117 111 118 if( !s ) 112 s = set_add( irc, key, NULL, NULL );113 114 if( s->eval && !( nv = s->eval( irc,s, value ) ) )115 return ( 0 );119 s = set_add( head, key, NULL, NULL, NULL ); 120 121 if( s->eval && !( nv = s->eval( s, value ) ) ) 122 return 0; 116 123 117 124 if( s->value ) … … 121 128 } 122 129 130 /* If there's a default setting and it's equal to what we're trying to 131 set, stick with s->value = NULL. Otherwise, remember the setting. */ 123 132 if( !s->def || ( strcmp( nv, s->def ) != 0 ) ) 124 133 s->value = g_strdup( nv ); … … 127 136 g_free( nv ); 128 137 129 return ( 1 );130 } 131 132 int set_setint( irc_t *irc, char *key, int value )138 return 1; 139 } 140 141 int set_setint( set_t **head, char *key, int value ) 133 142 { 134 143 char s[24]; /* Not quite 128-bit clean eh? ;-) */ 135 144 136 sprintf( s, "%d", value );137 return ( set_setstr( irc, key, s ));138 } 139 140 void set_del( irc_t *irc, char *key )141 { 142 set_t *s = irc->set, *t = NULL;145 g_snprintf( s, sizeof( s ), "%d", value ); 146 return set_setstr( head, key, s ); 147 } 148 149 void set_del( set_t **head, char *key ) 150 { 151 set_t *s = *head, *t = NULL; 143 152 144 153 while( s ) … … 153 162 t->next = s->next; 154 163 else 155 irc->set= s->next;164 *head = s->next; 156 165 157 166 g_free( s->key ); … … 162 171 } 163 172 164 char *set_eval_int( irc_t *irc,set_t *set, char *value )173 char *set_eval_int( set_t *set, char *value ) 165 174 { 166 175 char *s = value; 167 176 177 /* Allow a minus at the first position. */ 178 if( *s == '-' ) 179 s ++; 180 168 181 for( ; *s; s ++ ) 169 if( *s < '0' || *s > '9' ) 170 return( NULL ); 171 172 return( value ); 173 } 174 175 char *set_eval_bool( irc_t *irc, set_t *set, char *value ) 176 { 177 if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) 178 return( value ); 179 if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) 180 return( value ); 181 return( set_eval_int( irc, set, value ) ); 182 } 183 184 char *set_eval_to_char( irc_t *irc, set_t *set, char *value ) 182 if( !isdigit( *s ) ) 183 return NULL; 184 185 return value; 186 } 187 188 char *set_eval_bool( set_t *set, char *value ) 189 { 190 return is_bool( value ) ? value : NULL; 191 } 192 193 char *set_eval_to_char( set_t *set, char *value ) 185 194 { 186 195 char *s = g_new( char, 3 ); … … 191 200 sprintf( s, "%c ", *value ); 192 201 193 return( s ); 194 } 195 196 char *set_eval_ops( irc_t *irc, set_t *set, char *value ) 197 { 202 return s; 203 } 204 205 char *set_eval_ops( set_t *set, char *value ) 206 { 207 irc_t *irc = set->data; 208 198 209 if( g_strcasecmp( value, "user" ) == 0 ) 199 {200 210 irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost, 201 211 irc->channel, "+o-o", irc->nick, irc->mynick ); 202 return( value );203 }204 212 else if( g_strcasecmp( value, "root" ) == 0 ) 205 {206 213 irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost, 207 214 irc->channel, "-o+o", irc->nick, irc->mynick ); 208 return( value );209 }210 215 else if( g_strcasecmp( value, "both" ) == 0 ) 211 {212 216 irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost, 213 217 irc->channel, "+oo", irc->nick, irc->mynick ); 214 return( value );215 }216 218 else if( g_strcasecmp( value, "none" ) == 0 ) 217 {218 219 irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost, 219 220 irc->channel, "-oo", irc->nick, irc->mynick ); 220 return( value ); 221 } 222 223 return( NULL ); 224 } 225 221 else 222 return NULL; 223 224 return value; 225 } 226 227 char *set_eval_charset( set_t *set, char *value ) 228 { 229 GIConv cd; 230 231 if ( g_strncasecmp( value, "none", 4 ) == 0 ) 232 return value; 233 234 cd = g_iconv_open( "UTF-8", value ); 235 if( cd == (GIConv) -1 ) 236 return NULL; 237 238 g_iconv_close( cd ); 239 return value; 240 } -
set.h
rf4aa393 rd8d63a2 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-200 4Wilmer van der Gaast and others *4 * Copyright 2002-2006 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 24 24 */ 25 25 26 /* This used to be specific to irc_t structures, but it's more generic now 27 (so it can also be used for account_t structs). It's pretty simple, but 28 so far pretty useful. 29 30 In short, it just keeps a linked list of settings/variables and it also 31 remembers a default value for every setting. And to prevent the user 32 from setting invalid values, you can write an evaluator function for 33 every setting, which can check a new value and block it by returning 34 NULL, or replace it by returning a new value. See struct set.eval. */ 35 36 typedef char *(*set_eval) ( struct set *set, char *value ); 37 26 38 typedef struct set 27 39 { 40 void *data; /* Here you can save a pointer to the 41 object this settings belongs to. */ 42 28 43 char *key; 29 44 char *value; 30 char *def; /* Default */ 45 char *def; /* Default value. If the set_setstr() function 46 notices a new value is exactly the same as 47 the default, value gets set to NULL. So when 48 you read a setting, don't forget about this! */ 31 49 32 /* Eval: Returns NULL if the value is incorrect. Can return a 33 corrected value. set_setstr() should be able to free() the 34 returned string! */ 35 char *(*eval) ( irc_t *irc, struct set *set, char *value ); 50 int flags; /* See account.h, for example. set.c doesn't use 51 this (yet?). */ 52 53 /* Eval: Returns NULL if the value is incorrect or exactly the 54 passed value variable. When returning a corrected value, 55 set_setstr() should be able to free() the returned string! */ 56 set_eval eval; 36 57 struct set *next; 37 58 } set_t; 38 59 39 set_t *set_add( irc_t *irc, char *key, char *def, void *eval ); 40 G_MODULE_EXPORT set_t *set_find( irc_t *irc, char *key ); 41 G_MODULE_EXPORT char *set_getstr( irc_t *irc, char *key ); 42 G_MODULE_EXPORT int set_getint( irc_t *irc, char *key ); 43 int set_setstr( irc_t *irc, char *key, char *value ); 44 int set_setint( irc_t *irc, char *key, int value ); 45 void set_del( irc_t *irc, char *key ); 60 /* Should be pretty clear. */ 61 set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ); 46 62 47 char *set_eval_int( irc_t *irc, set_t *set, char *value ); 48 char *set_eval_bool( irc_t *irc, set_t *set, char *value ); 49 char *set_eval_to_char( irc_t *irc, set_t *set, char *value ); 50 char *set_eval_ops( irc_t *irc, set_t *set, char *value ); 63 /* Returns the raw set_t. Might be useful sometimes. */ 64 set_t *set_find( set_t **head, char *key ); 51 65 66 /* Returns a pointer to the string value of this setting. Don't modify the 67 returned string, and don't free() it! */ 68 G_MODULE_EXPORT char *set_getstr( set_t **head, char *key ); 52 69 70 /* Get an integer. Right now this also converts true/false/on/off/etc to 71 numbers, but this is for historical reasons, please use set_getbool() 72 for booleans instead. */ 73 G_MODULE_EXPORT int set_getint( set_t **head, char *key ); 74 G_MODULE_EXPORT int set_getbool( set_t **head, char *key ); 75 76 /* set_setstr() strdup()s the given value, so after using this function 77 you can free() it, if you want. */ 78 int set_setstr( set_t **head, char *key, char *value ); 79 int set_setint( set_t **head, char *key, int value ); 80 void set_del( set_t **head, char *key ); 81 82 /* Two very useful generic evaluators. */ 83 char *set_eval_int( set_t *set, char *value ); 84 char *set_eval_bool( set_t *set, char *value ); 85 86 /* Some not very generic evaluators that really shouldn't be here... */ 87 char *set_eval_to_char( set_t *set, char *value ); 88 char *set_eval_ops( set_t *set, char *value ); 89 char *set_eval_charset( set_t *set, char *value ); -
sock.h
rf4aa393 rd8d63a2 1 1 #include <errno.h> 2 2 #include <fcntl.h> 3 4 /* To cut down on the ifdef stuff a little bit in other places */5 #ifdef IPV66 #define AF_INETx AF_INET67 #else8 #define AF_INETx AF_INET9 #endif10 3 11 4 #ifndef _WIN32 -
storage.c
rf4aa393 rd8d63a2 6 6 7 7 /* Support for multiple storage backends */ 8 9 /* Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org> */ 8 10 9 11 /* … … 29 31 30 32 extern storage_t storage_text; 33 extern storage_t storage_xml; 31 34 32 static GList text_entry = { &storage_text, NULL, NULL }; 33 static GList *storage_backends = &text_entry; 35 static GList *storage_backends = NULL; 34 36 35 37 void register_storage_backend(storage_t *backend) … … 41 43 { 42 44 GList *gl; 43 storage_t *st ;45 storage_t *st = NULL; 44 46 45 47 for (gl = storage_backends; gl; gl = gl->next) { … … 63 65 int i; 64 66 storage_t *storage; 65 67 68 register_storage_backend(&storage_text); 69 register_storage_backend(&storage_xml); 70 66 71 storage = storage_init_single(primary); 67 if (storage == NULL )72 if (storage == NULL && storage->save == NULL) 68 73 return NULL; 69 74 -
storage.h
rf4aa393 rd8d63a2 33 33 STORAGE_ALREADY_EXISTS, 34 34 STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as 35 36 35 a database that is unreachable. log() will be 36 used for the exact error message */ 37 37 } storage_status_t; 38 38 -
storage_text.c
rf4aa393 rd8d63a2 28 28 #include "crypting.h" 29 29 30 /* DO NOT USE THIS FUNCTION IN NEW CODE. This31 * function is here merely because the save/load code still uses32 * ids rather than names */33 static struct prpl *find_protocol_by_id(int id)34 {35 switch (id) {36 case 0: case 1: case 3: return find_protocol("oscar");37 case 4: return find_protocol("msn");38 case 2: return find_protocol("yahoo");39 case 8: return find_protocol("jabber");40 default: break;41 }42 return NULL;43 }44 45 static int find_protocol_id(const char *name)46 {47 if (!strcmp(name, "oscar")) return 1;48 if (!strcmp(name, "msn")) return 4;49 if (!strcmp(name, "yahoo")) return 2;50 if (!strcmp(name, "jabber")) return 8;51 52 return -1;53 }54 55 56 30 static void text_init (void) 57 31 { 58 32 if( access( global.conf->configdir, F_OK ) != 0 ) 59 log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", CONFIG);33 log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", global.conf->configdir ); 60 34 else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 ) 61 35 log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir ); … … 70 44 FILE *fp; 71 45 user_t *ru = user_find( irc, ROOT_NICK ); 46 account_t *acc, *acc_lookup[9]; 72 47 73 48 if( irc->status & USTATUS_IDENTIFIED ) … … 80 55 fscanf( fp, "%32[^\n]s", s ); 81 56 82 if (checkpass (password, s) != 0)57 if( checkpass( password, s ) != 0 ) 83 58 { 84 59 fclose( fp ); … … 100 75 fclose( fp ); 101 76 77 /* Build a list with the first listed account of every protocol 78 number. So if the user had nicks defined for a second account on 79 the same IM network, those nicks will be added to the wrong 80 account, and the user should rename those buddies again. But at 81 least from now on things will be saved properly. */ 82 memset( acc_lookup, 0, sizeof( acc_lookup ) ); 83 for( acc = irc->accounts; acc; acc = acc->next ) 84 { 85 if( acc_lookup[0] == NULL && strcmp( acc->prpl->name, "oscar" ) == 0 ) 86 acc_lookup[0] = acc_lookup[1] = acc_lookup[3] = acc; 87 else if( acc_lookup[2] == NULL && strcmp( acc->prpl->name, "yahoo" ) == 0 ) 88 acc_lookup[2] = acc; 89 else if( acc_lookup[4] == NULL && strcmp( acc->prpl->name, "msn" ) == 0 ) 90 acc_lookup[4] = acc; 91 else if( acc_lookup[8] == NULL && strcmp( acc->prpl->name, "jabber" ) == 0 ) 92 acc_lookup[8] = acc; 93 } 94 102 95 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" ); 103 96 fp = fopen( s, "r" ); … … 105 98 while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 ) 106 99 { 107 struct prpl *prpl; 108 109 prpl = find_protocol_by_id(proto); 110 111 if (!prpl) 100 if( ( acc = acc_lookup[proto] ) == NULL ) 112 101 continue; 113 102 114 103 http_decode( s ); 115 nick_set( irc, s, prpl, nick );104 nick_set( acc, s, nick ); 116 105 } 117 106 fclose( fp ); 118 119 if( set_getint( irc, "auto_connect" ) )120 {121 strcpy( s, "account on" ); /* Can't do this directly because r_c_s alters the string */122 root_command_string( irc, ru, s, 0 );123 }124 125 return STORAGE_OK;126 }127 128 static storage_status_t text_save( irc_t *irc, int overwrite )129 {130 char s[512];131 char path[512], new_path[512];132 char *line;133 nick_t *n;134 set_t *set;135 mode_t ou = umask( 0077 );136 account_t *a;137 FILE *fp;138 char *hash;139 140 if (!overwrite) {141 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );142 if (access( path, F_OK ) != -1)143 return STORAGE_ALREADY_EXISTS;144 145 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );146 if (access( path, F_OK ) != -1)147 return STORAGE_ALREADY_EXISTS;148 }149 150 /*\151 * [SH] Nothing should be saved if no password is set, because the152 * password is not set if it was wrong, or if one is not identified153 * yet. This means that a malicious user could easily overwrite154 * files owned by someone else:155 * a Bad Thing, methinks156 \*/157 158 /* [WVG] No? Really? */159 160 /*\161 * [SH] Okay, okay, it wasn't really Wilmer who said that, it was162 * me. I just thought it was funny.163 \*/164 165 hash = hashpass( irc->password );166 if( hash == NULL )167 {168 irc_usermsg( irc, "Please register yourself if you want to save your settings." );169 return STORAGE_OTHER_ERROR;170 }171 172 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );173 fp = fopen( path, "w" );174 if( !fp ) return STORAGE_OTHER_ERROR;175 for( n = irc->nicks; n; n = n->next )176 {177 strcpy( s, n->handle );178 s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */179 http_encode( s );180 g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", find_protocol_id(n->proto->name), n->nick );181 if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )182 {183 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );184 fclose( fp );185 return STORAGE_OTHER_ERROR;186 }187 }188 if( fclose( fp ) != 0 )189 {190 irc_usermsg( irc, "fclose() reported an error. Disk full?" );191 return STORAGE_OTHER_ERROR;192 }193 194 g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );195 if( unlink( new_path ) != 0 )196 {197 if( errno != ENOENT )198 {199 irc_usermsg( irc, "Error while removing old .nicks file" );200 return STORAGE_OTHER_ERROR;201 }202 }203 if( rename( path, new_path ) != 0 )204 {205 irc_usermsg( irc, "Error while renaming new .nicks file" );206 return STORAGE_OTHER_ERROR;207 }208 209 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );210 fp = fopen( path, "w" );211 if( !fp ) return STORAGE_OTHER_ERROR;212 if( fprintf( fp, "%s", hash ) != strlen( hash ) )213 {214 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );215 fclose( fp );216 return STORAGE_OTHER_ERROR;217 }218 g_free( hash );219 220 for( a = irc->accounts; a; a = a->next )221 {222 if( !strcmp(a->prpl->name, "oscar") )223 g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );224 else225 g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",226 a->prpl->name, a->user, a->pass, a->server ? a->server : "" );227 228 line = obfucrypt( s, irc->password );229 if( *line )230 {231 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )232 {233 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );234 fclose( fp );235 return STORAGE_OTHER_ERROR;236 }237 }238 g_free( line );239 }240 241 for( set = irc->set; set; set = set->next )242 {243 if( set->value && set->def )244 {245 g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );246 line = obfucrypt( s, irc->password );247 if( *line )248 {249 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )250 {251 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );252 fclose( fp );253 return STORAGE_OTHER_ERROR;254 }255 }256 g_free( line );257 }258 }259 260 if( strcmp( irc->mynick, ROOT_NICK ) != 0 )261 {262 g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );263 line = obfucrypt( s, irc->password );264 if( *line )265 {266 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )267 {268 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );269 fclose( fp );270 return STORAGE_OTHER_ERROR;271 }272 }273 g_free( line );274 }275 if( fclose( fp ) != 0 )276 {277 irc_usermsg( irc, "fclose() reported an error. Disk full?" );278 return STORAGE_OTHER_ERROR;279 }280 281 g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );282 if( unlink( new_path ) != 0 )283 {284 if( errno != ENOENT )285 {286 irc_usermsg( irc, "Error while removing old .accounts file" );287 return STORAGE_OTHER_ERROR;288 }289 }290 if( rename( path, new_path ) != 0 )291 {292 irc_usermsg( irc, "Error while renaming new .accounts file" );293 return STORAGE_OTHER_ERROR;294 }295 296 umask( ou );297 107 298 108 return STORAGE_OK; … … 343 153 .check_pass = text_check_pass, 344 154 .remove = text_remove, 345 .load = text_load, 346 .save = text_save 155 .load = text_load 347 156 }; -
unix.c
rf4aa393 rd8d63a2 48 48 49 49 b_main_init(); 50 51 50 log_init(); 52 53 51