diff options
| -rw-r--r-- | bitlbee.c | 18 | ||||
| -rw-r--r-- | bitlbee.h | 1 | ||||
| -rwxr-xr-x | configure | 22 | ||||
| -rwxr-xr-x | debian/bitlbee.init | 10 | ||||
| -rw-r--r-- | debian/changelog | 50 | ||||
| -rwxr-xr-x | debian/config | 20 | ||||
| -rw-r--r-- | debian/control | 2 | ||||
| -rw-r--r-- | debian/patches/bitlbee.conf.diff | 19 | ||||
| -rw-r--r-- | debian/po/POTFILES.in | 2 | ||||
| -rw-r--r-- | debian/po/ru.po | 47 | ||||
| -rwxr-xr-x | debian/postinst | 9 | ||||
| -rwxr-xr-x | debian/prerm | 2 | ||||
| -rw-r--r-- | doc/CHANGES | 8 | ||||
| -rw-r--r-- | doc/user-guide/commands.xml | 12 | ||||
| -rw-r--r-- | irc.c | 1 | ||||
| -rw-r--r-- | irc_commands.c | 2 | ||||
| -rw-r--r-- | protocols/jabber/io.c | 12 | ||||
| -rw-r--r-- | protocols/jabber/iq.c | 8 | ||||
| -rw-r--r-- | protocols/jabber/jabber.c | 16 | ||||
| -rw-r--r-- | protocols/jabber/jabber.h | 11 | ||||
| -rw-r--r-- | protocols/jabber/jabber_util.c | 75 | ||||
| -rw-r--r-- | protocols/jabber/message.c | 2 | ||||
| -rw-r--r-- | protocols/jabber/presence.c | 3 | ||||
| -rw-r--r-- | protocols/nogaim.c | 13 | ||||
| -rw-r--r-- | protocols/yahoo/libyahoo2.c | 6 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo.c | 2 | ||||
| -rw-r--r-- | root_commands.c | 40 | ||||
| -rw-r--r-- | tests/check_jabber_util.c | 30 | ||||
| -rw-r--r-- | user.h | 1 | 
29 files changed, 311 insertions, 133 deletions
| @@ -108,17 +108,13 @@ int bitlbee_daemon_init()  		chdir( "/" ); -		i = close( 0 ) == 0; -		i += close( 1 ) == 0; -		i += close( 2 ) == 0; -		/* To avoid that something important ends up on one of those -		   fd's, open them for something bogus. Otherwise RESTART -		   may cause troubles. */ -		while( i > 0 ) -		{ -			open( "/dev/null", O_WRONLY ); -			i --; -		} +		if( getenv( "_BITLBEE_RESTART_STATE" ) == NULL ) +			for( i = 0; i < 3; i ++ ) +				if( close( i ) == 0 ) +				{ +					/* Keep something bogus on those fd's just in case. */ +					open( "/dev/null", O_WRONLY ); +				}  	}  #endif @@ -162,6 +162,7 @@ void root_command( irc_t *irc, char *command[] );  gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond );  char *set_eval_root_nick( set_t *set, char *new_nick ); +char *set_eval_control_channel( set_t *set, char *new_name );  extern global_t global; @@ -19,7 +19,7 @@ libevent='/usr/'  pidfile='/var/run/bitlbee.pid'  ipcsocket='/var/run/bitlbee.sock'  pcdir='$prefix/lib/pkgconfig' -systemlibdirs="/lib /usr/lib /usr/local/lib" +systemlibdirs="/lib /lib64 /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64"  msn=1  jabber=1 @@ -158,7 +158,7 @@ else  fi  echo CFLAGS=$CFLAGS >> Makefile.settings -echo CFLAGS+=-I`pwd` -iquote`pwd`/lib -iquote`pwd`/protocols -I. >> Makefile.settings +echo CFLAGS+=-I`pwd` -I`pwd`/lib -I`pwd`/protocols -I. >> Makefile.settings  echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings @@ -297,28 +297,34 @@ int main()  detect_resolv_dynamic()  { -	echo "$RESOLV_TESTCODE" | $CC -o /dev/null -x c - -lresolv >/dev/null 2>/dev/null +	TMPFILE=$(mktemp) +	ret=1 +	echo "$RESOLV_TESTCODE" | $CC -o $TMPFILE -x c - -lresolv >/dev/null 2>/dev/null  	if [ "$?" = "0" ]; then  		echo 'EFLAGS+=-lresolv' >> Makefile.settings -		return 0 +		ret=0  	fi -	return 1 +	rm -f $TMPFILE +	return $ret  }  detect_resolv_static()  { +	TMPFILE=$(mktemp) +	ret=1  	for i in $systemlibdirs; do  		if [ -f $i/libresolv.a ]; then -			echo "$RESOLV_TESTCODE" | $CC -o /dev/null -x c - -Wl,$i/libresolv.a >/dev/null 2>/dev/null +			echo "$RESOLV_TESTCODE" | $CC -o $TMPFILE -x c - -Wl,$i/libresolv.a >/dev/null 2>/dev/null  			if [ "$?" = "0" ]; then  				echo 'EFLAGS+='$i'/libresolv.a' >> Makefile.settings -				return 0 +				ret=0  			fi  		fi  	done -	return 1 +	rm -f $TMPFILE +	return $ret  }  if [ "$ssl" = "auto" ]; then diff --git a/debian/bitlbee.init b/debian/bitlbee.init index 1ab1bc43..4c224ffc 100755 --- a/debian/bitlbee.init +++ b/debian/bitlbee.init @@ -40,15 +40,7 @@ d_start() {  	touch /var/run/bitlbee.pid  	chown bitlbee: /var/run/bitlbee.pid -	# Clean up after the bug between 1.2-5 and 1.2.1-2 where BitlBee ran -	# as root. (#494656 and #495877) Fixing this in the postinst script -	# is not enough since the user will restart his BitlBee after up- -	# grading the package, and the BitlBee running as root will then -	# save its settings, re-setting ownership of the file to root. -	# TODO: Remove this after a few revisions. -	find /var/lib/bitlbee -uid 0 -name '*.xml' -exec chown bitlbee: {} \; - -	start-stop-daemon --start --quiet \ +	start-stop-daemon --start --quiet --pidfile $PIDFILE \  		--exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS  } diff --git a/debian/changelog b/debian/changelog index a11a67b8..f969b410 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,53 @@ +bitlbee (1.2.5-1) unstable; urgency=low + +  * New upstream version. +  * Fixed issues with server-side MSN nickname corruption. (Closes: #538756) +  * Debconf translation fixes/additions. (Closes: #541754, #563504) + + -- Wilmer van der Gaast <wilmer@gaast.net>  Wed, 17 Mar 2010 14:59:27 +0000 + +bitlbee (1.2.4-2) unstable; urgency=low + +  * Merging in some changes from bzr-head: +  * Use libresolv.so where possible. (Closes: #551775) +  * Some include file changes that make the bitlbee-dev package useful again. + + -- Wilmer van der Gaast <wilmer@gaast.net>  Thu, 19 Nov 2009 23:02:43 +0000 + +bitlbee (1.2.4-1) unstable; urgency=low + +  * New upstream version. +  * Fixed issues with Yahoo! (Closes: #536178) + + -- Wilmer van der Gaast <wilmer@gaast.net>  Sat, 17 Oct 2009 18:12:45 +0100 + +bitlbee (1.2.3-2) unstable; urgency=low + +  * Fixed bitblee typo in prerm (introduced by NMU 1.2.1-1.1). +    (Closes: #531287) +  * Fixed bitlbee.deb dep in bitlbee-dev to deal with binary NMUs. +    (Closes: #531219) +  * Fixed free port detection code in debian/config which was a bit limited +    and also buggy. +  * Removing code that edits bitlbee.conf from postinst (and chown code in +    the init script), it's not really necessary anymore; bitlbee may only +    still run as root if the admin doesn't read conffile diffs. +    (Closes: #514572) +  * No longer overwriting port number info in /etc/default/bitlbee with +    what's in debconf. (Closes: #514148) +  * Added notes about the above two changes to bitlbee.conf. + + -- Wilmer van der Gaast <wilmer@gaast.net>  Sun, 07 Jun 2009 21:17:39 +0100 + +bitlbee (1.2.3-1) unstable; urgency=critical + +  * New upstream version. +  * Fixes another account hijacking issue. (Closes: #498159) +  * Restored --pidfile argument to start-stop-daemon, otherwise the init +    script fails to restart BitlBee when users are connected. + + -- Wilmer van der Gaast <wilmer@gaast.net>  Sun, 07 Sep 2008 18:53:04 +0100 +  bitlbee (1.2.2-1) unstable; urgency=critical    * New upstream version. diff --git a/debian/config b/debian/config index 3a04813d..9bb78237 100755 --- a/debian/config +++ b/debian/config @@ -1,17 +1,23 @@  #!/bin/sh -e  . /usr/share/debconf/confmodule +[ -f /etc/default/bitlbee ] && . /etc/default/bitlbee  db_title BitlBee -db_get bitlbee/serveport -if [ "$RET" = "stillhavetoask" ]; then -	if netstat -ltn | grep ':6667' 2> /dev/null > /dev/null; then -		port=6668; -	else -		port=6667; +if [ -n "$BITLBEE_PORT" ]; then +	db_set bitlbee/serveport "$BITLBEE_PORT" +else +	db_get bitlbee/serveport +	if [ "$RET" = "stillhavetoask" ]; then +		listens=$(netstat -ltn | awk '{print $4}') +		for port in 6667 6666 6668 6669; do +			if [ $(expr "$listens " : ".*:$port\s") = "0" ]; then +				break +			fi +		done +		db_set bitlbee/serveport $port;  	fi -	db_set bitlbee/serveport $port;  fi  if db_input medium bitlbee/serveport; then diff --git a/debian/control b/debian/control index e6302c13..86488c8a 100644 --- a/debian/control +++ b/debian/control @@ -18,7 +18,7 @@ Description: An IRC to other chat networks gateway  Package: bitlbee-dev  Architecture: all -Depends: bitlbee (= ${binary:Version}) +Depends: bitlbee (>= ${source:Version}), bitlbee (<< ${source:Version}.1~)  Description: An IRC to other chat networks gateway   This program can be used as an IRC server which forwards everything you   say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo. diff --git a/debian/patches/bitlbee.conf.diff b/debian/patches/bitlbee.conf.diff index b80bcb4c..c98fa546 100644 --- a/debian/patches/bitlbee.conf.diff +++ b/debian/patches/bitlbee.conf.diff @@ -1,13 +1,22 @@ -=== modified file 'bitlbee.conf' ---- debian/bitlbee/etc/bitlbee/bitlbee.conf	2008-08-26 22:33:54 +0000 -+++ debian/bitlbee/etc/bitlbee/bitlbee.conf	2008-08-27 23:18:13 +0000 -@@ -23,7 +23,7 @@ +--- debian/bitlbee/etc/bitlbee/bitlbee.conf	2009-06-01 00:20:24.000000000 +0100 ++++ debian/bitlbee/etc/bitlbee/bitlbee.conf	2009-06-07 21:16:19.000000000 +0100 +@@ -23,13 +23,18 @@   ## If BitlBee is started by root as a daemon, it can drop root privileges,   ## and change to the specified user.   ##  -# User = bitlbee ++## DEBIAN NOTE: Without this, BitlBee will run as root! ++##  +User = bitlbee   ## DaemonPort/DaemonInterface:   ## - + ## For daemon mode, you can specify on what interface and port the daemon + ## should be listening for connections. + ## ++## DEBIAN NOTE: The init script passes the -p flag to use the port number ++## set using debconf, this overrides the DaemonPort setting here. ++## + # DaemonInterface = 0.0.0.0 + # DaemonPort = 6667 +  diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in index f17ddcfe..cef83a34 100644 --- a/debian/po/POTFILES.in +++ b/debian/po/POTFILES.in @@ -1 +1 @@ -[type: gettext/rfc822deb] bitlbee.templates.master +[type: gettext/rfc822deb] templates diff --git a/debian/po/ru.po b/debian/po/ru.po new file mode 100644 index 00000000..4e448133 --- /dev/null +++ b/debian/po/ru.po @@ -0,0 +1,47 @@ +# translation of ru.po to Russian +# +#    Translators, if you are not familiar with the PO format, gettext +#    documentation is worth reading, especially sections dedicated to +#    this format, e.g. by running: +#         info -n '(gettext)PO Files' +#         info -n '(gettext)Header Entry' +#    Some information specific to po-debconf are available at +#            /usr/share/doc/po-debconf/README-trans +#         or http://www.debian.org/intl/l10n/po-debconf/README-trans# +#    Developers do not need to manually edit POT or PO files. +# +# Yuri Kozlov <yuray@komyakino.ru>, 2009. +msgid "" +msgstr "" +"Project-Id-Version: bitlbee 1.2.3-2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2004-09-25 18:12+0200\n" +"PO-Revision-Date: 2009-08-05 20:43+0400\n" +"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n" +"Language-Team: Russian <debian-l10n-russian@lists.debian.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms:  nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. Type: string +#. Description +#: ../bitlbee.templates.master:4 +msgid "On what TCP port should BitlBee listen for connections?" +msgstr "Номер порта TCP, на котором BitlBee должен ожидать подключений:" + +#. Type: string +#. Description +#: ../bitlbee.templates.master:4 +msgid "" +"BitlBee normally listens on the regular IRC port, 6667. This might not be a " +"very good idea when you're running a real IRC daemon as well. 6668 might be " +"a good alternative. Leaving this value blank means that BitlBee will not be " +"run automatically." +msgstr "" +"Обычно, BitlBee прослушивает штатный порт IRC, 6667. Это может быть " +"не лучшим решением, если у вас также запущена служба IRC. Хорошей " +"альтернативой является номер 6668. Если оставить поле пустым, то " +"BitlBee не будет запускаться автоматически." + diff --git a/debian/postinst b/debian/postinst index db324b65..db541f6c 100755 --- a/debian/postinst +++ b/debian/postinst @@ -32,7 +32,7 @@ fi  cat<<EOF>/etc/default/bitlbee  ## /etc/default/bitlbee: Auto-generated/updated script.  ## -## Don't edit this line, use dpkg-reconfigure bitlbee +## If running in (fork)daemon mode, listen on this TCP port.  BITLBEE_PORT="$PORT"  ## Use single-process or forking daemon mode? Can't be changed from debconf, @@ -63,13 +63,6 @@ if [ -e /usr/share/bitlbee/help.upgrading ]; then  	fi  fi -if ! grep -qi '^User *= *' /etc/bitlbee/bitlbee.conf; then -	echo 'Updating configuration file, enabling User-setting...' -	if ! sed -i -e 's/# *User *= *.*/User = bitlbee/i' /etc/bitlbee/bitlbee.conf; then -		echo 'Failed! BitlBee may run as root now, please check your configs.' -	fi -fi -  if [ -n "$2" -a "$BITLBEE_UPGRADE_DONT_RESTART" != "1" ]; then  	if which invoke-rc.d >/dev/null 2>&1; then  		invoke-rc.d bitlbee restart diff --git a/debian/prerm b/debian/prerm index 8426ab3a..687c2cc1 100755 --- a/debian/prerm +++ b/debian/prerm @@ -10,7 +10,7 @@ if [ "$1" = "upgrade" ]; then  	fi  else  	if which invoke-rc.d >/dev/null 2>&1; then -		invoke-rc.d bitblee stop || exit 0 +		invoke-rc.d bitlbee stop || exit 0  	else  		/etc/init.d/bitlbee stop || exit 0  	fi diff --git a/doc/CHANGES b/doc/CHANGES index a0e9b30b..1cac2dc7 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -9,7 +9,8 @@ Version 1.2.5:  - Avoid linking in a static version of libresolv now that glibc has all    relevant functions available in the dynamic version.  - Improved away state code and added the ability to set (non-away) status -  messages using "set status" (also possible per account). +  messages using "set status" (also possible per account) and see them in +  blist and /whois output.  - Added a post-1.2 equivalent of encode/decode to quickly encrypt/decrypt    passwords in a way that BitlBee can read them.  - Allow using the full name for generating nicknames, instead of just the @@ -17,6 +18,11 @@ Version 1.2.5:  - Auto reconnect is now enabled by default since all protocols can properly    detect cases where auto reconnect should be avoided (i.e. concurrent    logins). +- Changed the default resource_select setting which should reduce message +  routing issues on Jabber (i.e. messages going someone's phone instead of +  the main client). + +Fixed 17 Mar 2010  Version 1.2.4:  - Most important change (and main reason for releasing now): Upgraded Yahoo! diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index 931608ee..f8ae4386 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -510,6 +510,16 @@  	</bitlbee-setting> +	<bitlbee-setting name="control_channel" type="string" scope="global"> +		<default>&bitlbee</default> + +		<description> +			<para> +				Normally the control channel where you can see all your contacts is called "&bitlbee". If you don't like this name, you can rename it to anything else using the <emphasis>rename</emphasis> command, or by changing this setting. +			</para> +		</description> +	</bitlbee-setting> +  	<bitlbee-setting name="debug" type="boolean" scope="global">  		<default>false</default> @@ -715,7 +725,7 @@  	</bitlbee-setting>  	<bitlbee-setting name="resource_select" type="string" scope="account"> -		<default>priority</default> +		<default>activity</default>  		<possible-values>priority, activity</possible-values>  		<description> @@ -170,6 +170,7 @@ irc_t *irc_new( int fd )  	s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );  	s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );  	s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); +	s = set_add( &irc->set, "control_channel", irc->channel, set_eval_control_channel, irc );  	s = set_add( &irc->set, "debug", "false", set_eval_bool, irc );  	s = set_add( &irc->set, "default_target", "root", NULL, irc );  	s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); diff --git a/irc_commands.c b/irc_commands.c index 750bbcf5..a417e0d9 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -496,6 +496,8 @@ static void irc_cmd_whois( irc_t *irc, char **cmd )  			irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );  		else if( u->away )  			irc_reply( irc, 301, "%s :%s", u->nick, u->away ); +		if( u->status_msg ) +			irc_reply( irc, 333, "%s :Status: %s", u->nick, u->status_msg );  		irc_reply( irc, 318, "%s :End of /WHOIS list", nick );  	} diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index bff4e6c8..d6f92a5f 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -379,18 +379,8 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data )  	if( ( c = xt_find_node( node->children, "session" ) ) )  		jd->flags |= JFLAG_WANT_SESSION; -	/* This flag is already set if we authenticated via SASL, so now -	   we can resume the session in the new stream, if we don't have -	   to bind/initialize the session. */ -	if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WANT_BIND | JFLAG_WANT_SESSION ) ) == 0 ) -	{ -		if( !jabber_get_roster( ic ) ) -			return XT_ABORT; -	} -	else if( jd->flags & JFLAG_AUTHENTICATED ) -	{ +	if( jd->flags & JFLAG_AUTHENTICATED )  		return jabber_pkt_bind_sess( ic, NULL, NULL ); -	}  	return XT_HANDLED;  } diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 21e52da6..1b76a761 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -306,23 +306,19 @@ xt_status jabber_pkt_bind_sess( struct im_connection *ic, struct xt_node *node,  		if( c && c->text_len && ( s = strchr( c->text, '/' ) ) &&  		    strcmp( s + 1, set_getstr( &ic->acc->set, "resource" ) ) != 0 )  			imcb_log( ic, "Server changed session resource string to `%s'", s + 1 ); -		 -		jd->flags &= ~JFLAG_WANT_BIND; -	} -	else if( node && ( c = xt_find_node( node->children, "session" ) ) ) -	{ -		jd->flags &= ~JFLAG_WANT_SESSION;  	}  	if( jd->flags & JFLAG_WANT_BIND )  	{  		reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) );  		xt_add_attr( reply, "xmlns", XMLNS_BIND ); +		jd->flags &= ~JFLAG_WANT_BIND;  	}  	else if( jd->flags & JFLAG_WANT_SESSION )  	{  		reply = xt_new_node( "session", NULL, NULL );  		xt_add_attr( reply, "xmlns", XMLNS_SESSION ); +		jd->flags &= ~JFLAG_WANT_SESSION;  	}  	if( reply != NULL ) diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index eca7d2d3..86320ada 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -57,6 +57,8 @@ static void jabber_init( account_t *acc )  	set_t *s;  	char str[16]; +	s = set_add( &acc->set, "activity_timeout", "600", set_eval_int, acc ); +	  	g_snprintf( str, sizeof( str ), "%d", jabber_port_list[0] );  	s = set_add( &acc->set, "port", str, set_eval_int, acc );  	s->flags |= ACC_SET_OFFLINE_ONLY; @@ -66,7 +68,7 @@ static void jabber_init( account_t *acc )  	s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );  	s->flags |= ACC_SET_OFFLINE_ONLY; -	s = set_add( &acc->set, "resource_select", "priority", NULL, acc ); +	s = set_add( &acc->set, "resource_select", "activity", NULL, acc );  	s = set_add( &acc->set, "server", NULL, set_eval_account, acc );  	s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; @@ -306,7 +308,7 @@ static int jabber_buddy_msg( struct im_connection *ic, char *who, char *message,  	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )  		bud = jabber_buddy_by_ext_jid( ic, who, 0 );  	else -		bud = jabber_buddy_by_jid( ic, who, 0 ); +		bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_BARE_OK );  	node = xt_new_node( "body", message, NULL );  	node = jabber_make_packet( "message", "chat", bud ? bud->full_jid : who, node ); @@ -351,17 +353,9 @@ static GList *jabber_away_states( struct im_connection *ic )  static void jabber_get_info( struct im_connection *ic, char *who )  { -	struct jabber_data *jd = ic->proto_data;  	struct jabber_buddy *bud; -	if( strchr( who, '/' ) ) -		bud = jabber_buddy_by_jid( ic, who, 0 ); -	else -	{ -		char *s = jabber_normalize( who ); -		bud = g_hash_table_lookup( jd->buddies, s ); -		g_free( s ); -	} +	bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_FIRST );  	while( bud )  	{ diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 8e3bf036..40cf3957 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -107,6 +107,13 @@ struct jabber_cache_entry  	jabber_cache_event func;  }; +/* Somewhat messy data structure: We have a hash table with the bare JID as +   the key and the head of a struct jabber_buddy list as the value. The head +   is always a bare JID. If the JID has other resources (often the case, +   except for some transports that don't support multiple resources), those +   follow. In that case, the bare JID at the beginning doesn't actually +   refer to a real session and should only be used for operations that +   support incomplete JIDs. */  struct jabber_buddy  {  	char *bare_jid; @@ -120,7 +127,7 @@ struct jabber_buddy  	struct jabber_away_state *away_state;  	char *away_message; -	time_t last_act; +	time_t last_msg;  	jabber_buddy_flags_t flags;  	struct jabber_buddy *next; @@ -208,6 +215,8 @@ typedef enum  	GET_BUDDY_CREAT = 1,	/* Try to create it, if necessary. */  	GET_BUDDY_EXACT = 2,	/* Get an exact match (only makes sense with bare JIDs). */  	GET_BUDDY_FIRST = 4,	/* No selection, simply get the first resource for this JID. */ +	GET_BUDDY_BARE = 8,	/* Get the bare version of the JID (possibly inexistent). */ +	GET_BUDDY_BARE_OK = 16,	/* Allow returning a bare JID if that seems better. */  } get_buddy_flags_t;  struct jabber_error diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 185d3878..db5944bc 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -3,7 +3,7 @@  *  BitlBee - An IRC to IM gateway                                           *  *  Jabber module - Misc. stuff                                              *  *                                                                           * -*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   * +*  Copyright 2006-2010 Wilmer van der Gaast <wilmer@gaast.net>                *                                                                           *  *  This program is free software; you can redistribute it and/or modify     *  *  it under the terms of the GNU General Public License as published by     * @@ -344,6 +344,11 @@ struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid_  	if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) )  	{ +		/* The first entry is always a bare JID. If there are more, we +		   should ignore the first one here. */ +		if( bud->next ) +			bud = bud->next; +		  		/* If this is a transport buddy or whatever, it can't have more  		   than one instance, so this is always wrong: */  		if( s == NULL || bud->resource == NULL ) @@ -378,10 +383,15 @@ struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid_  	}  	else  	{ -		/* Keep in mind that full_jid currently isn't really -		   a full JID... */ -		new->bare_jid = g_strdup( full_jid ); +		new->full_jid = new->bare_jid = g_strdup( full_jid );  		g_hash_table_insert( jd->buddies, new->bare_jid, new ); +		 +		if( s ) +		{ +			new->next = g_new0( struct jabber_buddy, 1 ); +			new->next->bare_jid = new->bare_jid; +			new = new->next; +		}  	}  	if( s ) @@ -407,7 +417,7 @@ struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid_  struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_, get_buddy_flags_t flags )  {  	struct jabber_data *jd = ic->proto_data; -	struct jabber_buddy *bud; +	struct jabber_buddy *bud, *head;  	char *s, *jid;  	jid = jabber_normalize( jid_ ); @@ -419,6 +429,11 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_,  		*s = 0;  		if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )  		{ +			bare_exists = 1; +			 +			if( bud->next ) +				bud = bud->next; +			  			/* Just return the first one for this bare JID. */  			if( flags & GET_BUDDY_FIRST )  			{ @@ -440,16 +455,9 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_,  				if( strcmp( bud->resource, s + 1 ) == 0 )  					break;  		} -		else -		{ -			/* This variable tells the if down here that the bare -			   JID already exists and we should feel free to add -			   more resources, if the caller asked for that. */ -			bare_exists = 1; -		}  		if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && -		    ( !bare_exists || imcb_find_buddy( ic, jid ) ) ) +		    ( bare_exists || imcb_find_buddy( ic, jid ) ) )  		{  			*s = '/';  			bud = jabber_buddy_add( ic, jid ); @@ -463,7 +471,8 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_,  		struct jabber_buddy *best_prio, *best_time;  		char *set; -		bud = g_hash_table_lookup( jd->buddies, jid ); +		head = g_hash_table_lookup( jd->buddies, jid ); +		bud = ( head && head->next ) ? head->next : head;  		g_free( jid ); @@ -480,22 +489,31 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_,  		else if( flags & GET_BUDDY_FIRST )  			/* Looks like the caller doesn't care about details. */  			return bud; +		else if( flags & GET_BUDDY_BARE ) +			return head;  		best_prio = best_time = bud;  		for( ; bud; bud = bud->next )  		{  			if( bud->priority > best_prio->priority )  				best_prio = bud; -			if( bud->last_act > best_time->last_act ) +			if( bud->last_msg > best_time->last_msg )  				best_time = bud;  		}  		if( ( set = set_getstr( &ic->acc->set, "resource_select" ) ) == NULL )  			return NULL; -		else if( strcmp( set, "activity" ) == 0 ) -			return best_time; -		else /* if( strcmp( set, "priority" ) == 0 ) */ +		else if( strcmp( set, "priority" ) == 0 )  			return best_prio; +		else if( flags & GET_BUDDY_BARE_OK ) /* && strcmp( set, "activity" ) == 0 */ +		{ +			if( best_time->last_msg + set_getint( &ic->acc->set, "activity_timeout" ) >= time( NULL ) ) +				return best_time; +			else +				return head; +		} +		else +			return best_time;  	}  } @@ -537,7 +555,7 @@ struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *ji  int jabber_buddy_remove( struct im_connection *ic, char *full_jid_ )  {  	struct jabber_data *jd = ic->proto_data; -	struct jabber_buddy *bud, *prev, *bi; +	struct jabber_buddy *bud, *prev = NULL, *bi;  	char *s, *full_jid;  	full_jid = jabber_normalize( full_jid_ ); @@ -547,6 +565,9 @@ int jabber_buddy_remove( struct im_connection *ic, char *full_jid_ )  	if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) )  	{ +		if( bud->next ) +			bud = (prev=bud)->next; +		  		/* If there's only one item in the list (and if the resource  		   matches), removing it is simple. (And the hash reference  		   should be removed too!) */ @@ -554,16 +575,7 @@ int jabber_buddy_remove( struct im_connection *ic, char *full_jid_ )  		    ( ( s == NULL && bud->resource == NULL ) ||  		      ( bud->resource && s && strcmp( bud->resource, s + 1 ) == 0 ) ) )  		{ -			g_hash_table_remove( jd->buddies, bud->bare_jid ); -			g_free( bud->bare_jid ); -			g_free( bud->ext_jid ); -			g_free( bud->full_jid ); -			g_free( bud->away_message ); -			g_free( bud ); -			 -			g_free( full_jid ); -			 -			return 1; +			return jabber_buddy_remove_bare( ic, full_jid );  		}  		else if( s == NULL || bud->resource == NULL )  		{ @@ -574,7 +586,7 @@ int jabber_buddy_remove( struct im_connection *ic, char *full_jid_ )  		}  		else  		{ -			for( bi = bud, prev = NULL; bi; bi = (prev=bi)->next ) +			for( bi = bud; bi; bi = (prev=bi)->next )  				if( strcmp( bi->resource, s + 1 ) == 0 )  					break; @@ -585,8 +597,7 @@ int jabber_buddy_remove( struct im_connection *ic, char *full_jid_ )  				if( prev )  					prev->next = bi->next;  				else -					/* The hash table should point at the second -					   item, because we're removing the first. */ +					/* Don't think this should ever happen anymore. */  					g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next );  				g_free( bi->ext_jid ); diff --git a/protocols/jabber/message.c b/protocols/jabber/message.c index 6cb67d42..a226a225 100644 --- a/protocols/jabber/message.c +++ b/protocols/jabber/message.c @@ -70,7 +70,7 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )  		{  			if( bud )  			{ -				bud->last_act = time( NULL ); +				bud->last_msg = time( NULL );  				from = bud->ext_jid ? : bud->bare_jid;  			}  			else diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c index 28aaea1b..006eeead 100644 --- a/protocols/jabber/presence.c +++ b/protocols/jabber/presence.c @@ -67,9 +67,6 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )  		else  		{  			bud->away_state = NULL; -			/* Let's only set last_act if there's *no* away state, -			   since it could be some auto-away thingy. */ -			bud->last_act = time( NULL );  		}  		if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 ) diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 96c2f512..b9426696 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -654,11 +654,9 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  	oa = u->away != NULL;  	oo = u->online; -	if( u->away ) -	{ -		g_free( u->away ); -		u->away = NULL; -	} +	g_free( u->away ); +	g_free( u->status_msg ); +	u->away = u->status_msg = NULL;  	if( ( flags & OPT_LOGGED_IN ) && !u->online )  	{ @@ -696,7 +694,10 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  			u->away = g_strdup( "Away" );  		}  	} -	/* else waste_any_state_information_for_now(); */ +	else +	{ +		u->status_msg = g_strdup( message ); +	}  	/* LISPy... */  	if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */ diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 5b2ff44e..1bfc2e59 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -1343,7 +1343,11 @@ static void yahoo_process_status(struct yahoo_input_data *yid,  			break;  		case 301:	/* End buddy */  			if (!strcmp(pair->value, "315") && u) { -				users = y_list_prepend(users, u); +				/* Sometimes user info comes in an odd format with no +				   "begin buddy" but *with* an "end buddy". Don't add +				   it twice. */ +				if (!y_list_find(users, u)) +					users = y_list_prepend(users, u);  				u = yd->half_user = NULL;  			}  			break; diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 90466be3..b3d6ea1b 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -226,7 +226,7 @@ static void byahoo_set_away( struct im_connection *ic, char *state, char *msg )  		else  			yd->current_status = YAHOO_STATUS_CUSTOM;  	} -	else if( state ) +	else if( msg )  		yd->current_status = YAHOO_STATUS_CUSTOM;  	else  		yd->current_status = YAHOO_STATUS_AVAILABLE; diff --git a/root_commands.c b/root_commands.c index b3432b9b..e4e07605 100644 --- a/root_commands.c +++ b/root_commands.c @@ -1,7 +1,7 @@    /********************************************************************\    * BitlBee -- An IRC to other IM-networks gateway                     *    *                                                                    * -  * Copyright 2002-2004 Wilmer van der Gaast and others                * +  * Copyright 2002-2010 Wilmer van der Gaast and others                *    \********************************************************************/  /* User manager (root) commands                                         */ @@ -653,6 +653,21 @@ static void cmd_rename( irc_t *irc, char **cmd )  	{  		irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] );  	} +	else if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) +	{ +		if( strchr( CTYPES, cmd[2][0] ) && nick_ok( cmd[2] + 1 ) ) +		{ +			u = user_find( irc, irc->nick ); +			 +			irc_part( irc, u, irc->channel ); +			g_free( irc->channel ); +			irc->channel = g_strdup( cmd[2] ); +			irc_join( irc, u, irc->channel ); +			 +			if( strcmp( cmd[0], "set_rename" ) != 0 ) +				set_setstr( &irc->set, "control_channel", cmd[2] ); +		} +	}  	else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) )  	{  		irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); @@ -702,6 +717,20 @@ char *set_eval_root_nick( set_t *set, char *new_nick )  	return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID;  } +char *set_eval_control_channel( set_t *set, char *new_name ) +{ +	irc_t *irc = set->data; +	 +	if( strcmp( irc->channel, new_name ) != 0 ) +	{ +		char *cmd[] = { "set_rename", irc->channel, new_name, NULL }; +		 +		cmd_rename( irc, cmd ); +	} +	 +	return strcmp( irc->channel, new_name ) == 0 ? new_name : SET_INVALID; +} +  static void cmd_remove( irc_t *irc, char **cmd )  {  	user_t *u; @@ -913,7 +942,7 @@ static void cmd_blist( irc_t *irc, char **cmd )  	else if( cmd[1] && g_strcasecmp( cmd[1], "online" ) == 0 )  		online = 1;  	else -		online =  away = 1; +		online = away = 1;  	if( strchr( irc->umode, 'b' ) != NULL )  		format = "%s\t%s\t%s"; @@ -926,8 +955,13 @@ static void cmd_blist( irc_t *irc, char **cmd )  	{  		if( online == 1 )  		{ +			char st[256] = "Online"; +			 +			if( u->status_msg ) +				g_snprintf( st, sizeof( st ) - 1, "Online (%s)", u->status_msg ); +			  			g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user ); -			irc_usermsg( irc, format, u->nick, s, "Online" ); +			irc_usermsg( irc, format, u->nick, s, st );  		}  		n_online ++; diff --git a/tests/check_jabber_util.c b/tests/check_jabber_util.c index 4728c5ee..bf6d3e60 100644 --- a/tests/check_jabber_util.c +++ b/tests/check_jabber_util.c @@ -13,12 +13,12 @@ static void check_buddy_add(int l)  	struct jabber_buddy *budw1, *budw2, *budw3, *budn, *bud;  	budw1 = jabber_buddy_add( ic, "wilmer@gaast.net/BitlBee" ); -	budw1->last_act = time( NULL ) - 100; +	budw1->last_msg = time( NULL ) - 100;  	budw2 = jabber_buddy_add( ic, "WILMER@gaast.net/Telepathy" );  	budw2->priority = 2; -	budw2->last_act = time( NULL ); +	budw2->last_msg = time( NULL );  	budw3 = jabber_buddy_add( ic, "wilmer@GAAST.NET/bitlbee" ); -	budw3->last_act = time( NULL ) - 200; +	budw3->last_msg = time( NULL ) - 200;  	budw3->priority = 4;  	/* TODO(wilmer): Shouldn't this just return budw3? */  	fail_if( jabber_buddy_add( ic, "wilmer@gaast.net/Telepathy" ) != NULL ); @@ -59,18 +59,39 @@ static void check_buddy_add(int l)  	fail_if( jabber_buddy_by_jid( ic, "wilmer@GAAST.NET/telepathy", GET_BUDDY_CREAT ) == budw2 );  	fail_unless( jabber_buddy_remove( ic, "wilmer@gaast.net/Telepathy" ) );  	fail_unless( jabber_buddy_remove( ic, "wilmer@gaast.net/telepathy" ) ); -	fail_unless( jabber_buddy_by_jid( ic, "wilmer@gaast.net", 0 ) == budw1 ); +	 +	/* Test activity_timeout and GET_BUDDY_BARE_OK. */ +	fail_unless( jabber_buddy_by_jid( ic, "wilmer@gaast.net", GET_BUDDY_BARE_OK ) == budw1 ); +	budw1->last_msg -= 50; +	fail_unless( ( bud = jabber_buddy_by_jid( ic, "wilmer@gaast.net", GET_BUDDY_BARE_OK ) ) != NULL ); +	fail_unless( strcmp( bud->full_jid, "wilmer@gaast.net" ) == 0 );  	fail_if( jabber_buddy_remove( ic, "wilmer@gaast.net" ) );  	fail_unless( jabber_buddy_by_jid( ic, "wilmer@gaast.net", 0 ) == budw1 ); +	fail_if( jabber_buddy_remove( ic, "wilmer@gaast.net" ) ); +	fail_unless( jabber_buddy_remove( ic, "wilmer@gaast.net/bitlbee" ) ); +	fail_unless( jabber_buddy_remove( ic, "wilmer@gaast.net/BitlBee" ) ); +	fail_if( jabber_buddy_by_jid( ic, "wilmer@gaast.net", GET_BUDDY_BARE_OK ) ); +	  	/* Check if remove_bare() indeed gets rid of all. */ +	/* disable this one for now.  	fail_unless( jabber_buddy_remove_bare( ic, "wilmer@gaast.net" ) );  	fail_if( jabber_buddy_by_jid( ic, "wilmer@gaast.net", 0 ) ); +	*/  	fail_if( jabber_buddy_remove( ic, "nekkid@lamejab.net/Illegal" ) );  	fail_unless( jabber_buddy_remove( ic, "nekkid@lamejab.net" ) );  	fail_if( jabber_buddy_by_jid( ic, "nekkid@lamejab.net", 0 ) ); +	 +	/* Fixing a bug in this branch that caused information to get lost when +	   removing the first full JID from a list. */ +	jabber_buddy_add( ic, "bugtest@google.com/A" ); +	jabber_buddy_add( ic, "bugtest@google.com/B" ); +	jabber_buddy_add( ic, "bugtest@google.com/C" ); +	fail_unless( jabber_buddy_remove( ic, "bugtest@google.com/A" ) ); +	fail_unless( jabber_buddy_remove( ic, "bugtest@google.com/B" ) ); +	fail_unless( jabber_buddy_remove( ic, "bugtest@google.com/C" ) );  }  Suite *jabber_util_suite (void) @@ -84,6 +105,7 @@ Suite *jabber_util_suite (void)  	ic->proto_data = jd = g_new0( struct jabber_data, 1 );  	jd->buddies = g_hash_table_new( g_str_hash, g_str_equal );  	set_add( &ic->acc->set, "resource_select", "priority", NULL, ic->acc ); +	set_add( &ic->acc->set, "activity_timeout", "120", NULL, ic->acc );  	suite_add_tcase (s, tc_core);  	tcase_add_test (tc_core, check_buddy_add); @@ -33,6 +33,7 @@ typedef struct __USER  	char *realname;  	char *away; +	char *status_msg; /* Non-IRC extension, but nice on IM. */  	char is_private;  	char online; | 
