aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.c18
-rw-r--r--bitlbee.h1
-rwxr-xr-xconfigure22
-rwxr-xr-xdebian/bitlbee.init10
-rw-r--r--debian/changelog50
-rwxr-xr-xdebian/config20
-rw-r--r--debian/control2
-rw-r--r--debian/patches/bitlbee.conf.diff19
-rw-r--r--debian/po/POTFILES.in2
-rw-r--r--debian/po/ru.po47
-rwxr-xr-xdebian/postinst9
-rwxr-xr-xdebian/prerm2
-rw-r--r--doc/CHANGES8
-rw-r--r--doc/user-guide/commands.xml12
-rw-r--r--irc.c1
-rw-r--r--irc_commands.c2
-rw-r--r--protocols/jabber/io.c12
-rw-r--r--protocols/jabber/iq.c8
-rw-r--r--protocols/jabber/jabber.c16
-rw-r--r--protocols/jabber/jabber.h11
-rw-r--r--protocols/jabber/jabber_util.c75
-rw-r--r--protocols/jabber/message.c2
-rw-r--r--protocols/jabber/presence.c3
-rw-r--r--protocols/nogaim.c13
-rw-r--r--protocols/yahoo/libyahoo2.c6
-rw-r--r--protocols/yahoo/yahoo.c2
-rw-r--r--root_commands.c40
-rw-r--r--tests/check_jabber_util.c30
-rw-r--r--user.h1
29 files changed, 311 insertions, 133 deletions
diff --git a/bitlbee.c b/bitlbee.c
index 9e040f59..b301ff89 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -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
diff --git a/bitlbee.h b/bitlbee.h
index 15592020..5f98deef 100644
--- a/bitlbee.h
+++ b/bitlbee.h
@@ -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;
diff --git a/configure b/configure
index fe4649c0..6cc3db27 100755
--- a/configure
+++ b/configure
@@ -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>&amp;bitlbee</default>
+
+ <description>
+ <para>
+ Normally the control channel where you can see all your contacts is called "&amp;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>
diff --git a/irc.c b/irc.c
index c6d4b9a7..11ad7895 100644
--- a/irc.c
+++ b/irc.c
@@ -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);
diff --git a/user.h b/user.h
index 9d8a41a0..8c4f9c44 100644
--- a/user.h
+++ b/user.h
@@ -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;