aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-08-14 14:44:35 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-08-14 14:44:35 +0100
commit07874bef9e9c4e6ace44e4d0605ce1aec89cad74 (patch)
treec2a0a0bc30f2fcec7af83b2fb3fe59bbec393116
parent584867592546f43f857645e02169d135f0df25e8 (diff)
parent136c2bb632715ab83710c93c7b339c5cca7d2679 (diff)
Merge mainline stuff.
-rw-r--r--doc/user-guide/commands.xml4
-rw-r--r--irc.h1
-rw-r--r--irc_channel.c25
-rw-r--r--irc_im.c16
-rw-r--r--irc_send.c7
-rw-r--r--irc_user.c6
-rw-r--r--lib/misc.c80
-rw-r--r--lib/misc.h3
-rw-r--r--protocols/jabber/jabber.c18
-rw-r--r--protocols/twitter/twitter.c2
-rw-r--r--protocols/twitter/twitter_lib.c7
-rw-r--r--root_commands.c12
-rw-r--r--sock.h2
13 files changed, 123 insertions, 60 deletions
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml
index 7cedffc3..8bbada95 100644
--- a/doc/user-guide/commands.xml
+++ b/doc/user-guide/commands.xml
@@ -1431,11 +1431,11 @@
<bitlbee-command name="blist">
<syntax>blist [all|online|offline|away]</syntax>
- <short-description>List all the buddies in your contact list</short-description>
+ <short-description>List all the buddies in the current channel</short-description>
<description>
<para>
- You can get a better readable buddy list using the <emphasis>blist</emphasis> command. If you want a complete list (including the offline users) you can use the <emphasis>all</emphasis> argument.
+ You can get a more readable buddy list using the <emphasis>blist</emphasis> command. If you want a complete list (including the offline users) you can use the <emphasis>all</emphasis> argument.
</para>
</description>
diff --git a/irc.h b/irc.h
index aee9dccd..58ca19c9 100644
--- a/irc.h
+++ b/irc.h
@@ -257,6 +257,7 @@ void irc_channel_name_strip( char *name );
int irc_channel_name_cmp( const char *a_, const char *b_ );
void irc_channel_update_ops( irc_channel_t *ic, char *value );
char *set_eval_irc_channel_ops( struct set *set, char *value );
+gboolean irc_channel_wants_user( irc_channel_t *ic, irc_user_t *iu );
/* irc_commands.c */
void irc_exec( irc_t *irc, char **cmd );
diff --git a/irc_channel.c b/irc_channel.c
index 0498cffa..118fef74 100644
--- a/irc_channel.c
+++ b/irc_channel.c
@@ -725,6 +725,31 @@ fail:
return SET_INVALID;
}
+/* Figure out if a channel is supposed to have the user, assuming s/he is
+ online or otherwise also selected by the show_users setting. Only works
+ for control channels, but does *not* check if this channel is of that
+ type. Beware! */
+gboolean irc_channel_wants_user( irc_channel_t *ic, irc_user_t *iu )
+{
+ struct irc_control_channel *icc = ic->data;
+
+ if( iu->bu == NULL )
+ return FALSE;
+
+ switch( icc->type )
+ {
+ case IRC_CC_TYPE_GROUP:
+ return iu->bu->group == icc->group;
+ case IRC_CC_TYPE_ACCOUNT:
+ return iu->bu->ic->acc == icc->account;
+ case IRC_CC_TYPE_PROTOCOL:
+ return iu->bu->ic->acc->prpl == icc->protocol;
+ case IRC_CC_TYPE_DEFAULT:
+ default:
+ return TRUE;
+ }
+}
+
static gboolean control_channel_free( irc_channel_t *ic )
{
struct irc_control_channel *icc = ic->data;
diff --git a/irc_im.c b/irc_im.c
index 2d4e8787..7ed2922e 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -140,9 +140,7 @@ static gboolean bee_irc_user_status( bee_t *bee, bee_user_t *bu, bee_user_t *old
void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu )
{
- struct irc_control_channel *icc;
GSList *l;
- gboolean match = FALSE;
if( ic == NULL )
{
@@ -167,23 +165,13 @@ void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu )
return;
}
- icc = ic->data;
-
- if( icc->type == IRC_CC_TYPE_DEFAULT )
- match = TRUE;
- else if( icc->type == IRC_CC_TYPE_GROUP )
- match = iu->bu->group == icc->group;
- else if( icc->type == IRC_CC_TYPE_ACCOUNT )
- match = iu->bu->ic->acc == icc->account;
- else if( icc->type == IRC_CC_TYPE_PROTOCOL )
- match = iu->bu->ic->acc->prpl == icc->protocol;
-
- if( !match )
+ if( !irc_channel_wants_user( ic, iu ) )
{
irc_channel_del_user( ic, iu, IRC_CDU_PART, NULL );
}
else
{
+ struct irc_control_channel *icc = ic->data;
int mode = 0;
if( !( iu->bu->flags & BEE_USER_ONLINE ) )
diff --git a/irc_send.c b/irc_send.c
index 003e0625..cb387059 100644
--- a/irc_send.c
+++ b/irc_send.c
@@ -43,9 +43,10 @@ void irc_send_login( irc_t *irc )
irc_send_num( irc, 2, ":Host %s is running BitlBee " BITLBEE_VERSION " " ARCH "/" CPU ".", irc->root->host );
irc_send_num( irc, 3, ":%s", IRCD_INFO );
irc_send_num( irc, 4, "%s %s %s %s", irc->root->host, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES );
- irc_send_num( irc, 5, "PREFIX=(ov)@+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee "
- "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server",
- CTYPES, CMODES, MAX_NICK_LENGTH - 1 );
+ irc_send_num( irc, 5, "PREFIX=(ohv)@%%+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d CHANNELLEN=%d "
+ "NETWORK=BitlBee SAFELIST CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 "
+ ":are supported by this server",
+ CTYPES, CMODES, MAX_NICK_LENGTH - 1, MAX_NICK_LENGTH - 1 );
irc_send_motd( irc );
}
diff --git a/irc_user.c b/irc_user.c
index 8b290bbf..bf08c755 100644
--- a/irc_user.c
+++ b/irc_user.c
@@ -210,7 +210,11 @@ void irc_user_quit( irc_user_t *iu, const char *msg )
return;
for( l = iu->irc->channels; l; l = l->next )
- send_quit |= irc_channel_del_user( (irc_channel_t*) l->data, iu, IRC_CDU_SILENT, NULL );
+ {
+ irc_channel_t *ic = l->data;
+ send_quit |= irc_channel_del_user( ic, iu, IRC_CDU_SILENT, NULL ) &&
+ ( ic->flags & IRC_CHANNEL_JOINED );
+ }
if( send_quit )
irc_send_quit( iu, msg );
diff --git a/lib/misc.c b/lib/misc.c
index 22832221..55575d8f 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -504,16 +504,17 @@ int bool2int( char *value )
return 0;
}
-struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain )
+struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain )
{
- struct ns_srv_reply *reply = NULL;
+ struct ns_srv_reply **replies = NULL;
#ifdef HAVE_RESOLV_A
+ struct ns_srv_reply *reply = NULL;
char name[1024];
unsigned char querybuf[1024];
const unsigned char *buf;
ns_msg nsh;
ns_rr rr;
- int i, len, size;
+ int i, n, len, size;
g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain );
@@ -523,37 +524,56 @@ struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain )
if( ns_initparse( querybuf, size, &nsh ) != 0 )
return NULL;
- if( ns_parserr( &nsh, ns_s_an, 0, &rr ) != 0 )
- return NULL;
-
- size = ns_rr_rdlen( rr );
- buf = ns_rr_rdata( rr );
-
- len = 0;
- for( i = 6; i < size && buf[i]; i += buf[i] + 1 )
- len += buf[i] + 1;
-
- if( i > size )
- return NULL;
-
- reply = g_malloc( sizeof( struct ns_srv_reply ) + len );
- memcpy( reply->name, buf + 7, len );
-
- for( i = buf[6]; i < len && buf[7+i]; i += buf[7+i] + 1 )
- reply->name[i] = '.';
-
- if( i > len )
+ n = 0;
+ while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 )
{
- g_free( reply );
- return NULL;
+ size = ns_rr_rdlen( rr );
+ buf = ns_rr_rdata( rr );
+
+ len = 0;
+ for( i = 6; i < size && buf[i]; i += buf[i] + 1 )
+ len += buf[i] + 1;
+
+ if( i > size )
+ break;
+
+ reply = g_malloc( sizeof( struct ns_srv_reply ) + len );
+ memcpy( reply->name, buf + 7, len );
+
+ for( i = buf[6]; i < len && buf[7+i]; i += buf[7+i] + 1 )
+ reply->name[i] = '.';
+
+ if( i > len )
+ {
+ g_free( reply );
+ break;
+ }
+
+ reply->prio = ( buf[0] << 8 ) | buf[1];
+ reply->weight = ( buf[2] << 8 ) | buf[3];
+ reply->port = ( buf[4] << 8 ) | buf[5];
+
+ n ++;
+ replies = g_renew( struct ns_srv_reply *, replies, n + 1 );
+ replies[n-1] = reply;
}
-
- reply->prio = ( buf[0] << 8 ) | buf[1];
- reply->weight = ( buf[2] << 8 ) | buf[3];
- reply->port = ( buf[4] << 8 ) | buf[5];
+ if( replies )
+ replies[n] = NULL;
#endif
- return reply;
+ return replies;
+}
+
+void srv_free( struct ns_srv_reply **srv )
+{
+ int i;
+
+ if( srv == NULL )
+ return;
+
+ for( i = 0; srv[i]; i ++ )
+ g_free( srv[i] );
+ g_free( srv );
}
/* Word wrapping. Yes, I know this isn't UTF-8 clean. I'm willing to take the risk. */
diff --git a/lib/misc.h b/lib/misc.h
index 12a9edff..83ba9e67 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -60,7 +60,8 @@ G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count );
G_MODULE_EXPORT int is_bool( char *value );
G_MODULE_EXPORT int bool2int( char *value );
-G_MODULE_EXPORT struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain );
+G_MODULE_EXPORT struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain );
+G_MODULE_EXPORT void srv_free( struct ns_srv_reply **srv );
G_MODULE_EXPORT char *word_wrap( const char *msg, int line_len );
diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c
index 229e35bf..f7e1e664 100644
--- a/protocols/jabber/jabber.c
+++ b/protocols/jabber/jabber.c
@@ -95,7 +95,7 @@ static void jabber_login( account_t *acc )
{
struct im_connection *ic = imcb_new( acc );
struct jabber_data *jd = g_new0( struct jabber_data, 1 );
- struct ns_srv_reply *srv = NULL;
+ struct ns_srv_reply **srvl = NULL, *srv = NULL;
char *connect_to, *s;
int i;
@@ -195,9 +195,19 @@ static void jabber_login( account_t *acc )
/* Figure out the hostname to connect to. */
if( acc->server && *acc->server )
connect_to = acc->server;
- else if( ( srv = srv_lookup( "xmpp-client", "tcp", jd->server ) ) ||
- ( srv = srv_lookup( "jabber-client", "tcp", jd->server ) ) )
+ else if( ( srvl = srv_lookup( "xmpp-client", "tcp", jd->server ) ) ||
+ ( srvl = srv_lookup( "jabber-client", "tcp", jd->server ) ) )
+ {
+ /* Find the lowest-priority one. These usually come
+ back in random/shuffled order. Not looking at
+ weights etc for now. */
+ srv = *srvl;
+ for( i = 1; srvl[i]; i ++ )
+ if( srvl[i]->prio < srv->prio )
+ srv = srvl[i];
+
connect_to = srv->name;
+ }
else
connect_to = jd->server;
@@ -226,7 +236,7 @@ static void jabber_login( account_t *acc )
{
jd->fd = proxy_connect( connect_to, srv ? srv->port : set_getint( &acc->set, "port" ), jabber_connected_plain, ic );
}
- g_free( srv );
+ srv_free( srvl );
if( jd->fd == -1 )
{
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c
index a2f2325c..d5b71bc3 100644
--- a/protocols/twitter/twitter.c
+++ b/protocols/twitter/twitter.c
@@ -256,7 +256,7 @@ static void twitter_logout( struct im_connection *ic )
struct twitter_data *td = ic->proto_data;
// Set the status to logged out.
- ic->flags = 0;
+ ic->flags &= ~ OPT_LOGGED_IN;
// Remove the main_loop function from the function queue.
b_event_remove(td->main_loop_id);
diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c
index f9e808f7..22d2a3bd 100644
--- a/protocols/twitter/twitter_lib.c
+++ b/protocols/twitter/twitter_lib.c
@@ -356,6 +356,11 @@ static xt_status twitter_xt_get_user_list( struct xt_node *node, struct twitter_
return XT_HANDLED;
}
+#ifdef __GLIBC__
+#define TWITTER_TIME_FORMAT "%a %b %d %H:%M:%S %z %Y"
+#else
+#define TWITTER_TIME_FORMAT "%a %b %d %H:%M:%S +0000 %Y"
+#endif
/**
* Function to fill a twitter_xml_status struct.
@@ -392,7 +397,7 @@ static xt_status twitter_xt_get_status( struct xt_node *node, struct twitter_xml
/* Very sensitive to changes to the formatting of
this field. :-( Also assumes the timezone used
is UTC since C time handling functions suck. */
- if( strptime( child->text, "%a %b %d %H:%M:%S %z %Y", &parsed ) != NULL )
+ if( strptime( child->text, TWITTER_TIME_FORMAT, &parsed ) != NULL )
txs->created_at = mktime_utc( &parsed );
}
else if (g_strcasecmp( "user", child->name ) == 0)
diff --git a/root_commands.c b/root_commands.c
index 6bd953fc..2cd1a617 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -1007,12 +1007,16 @@ static void cmd_blist( irc_t *irc, char **cmd )
irc_usermsg( irc, format, "Nick", "Handle/Account", "Status" );
+ if( strcmp( set_getstr( &irc->root->last_channel->set, "type" ), "control" ) != 0 )
+ irc->root->last_channel = NULL;
+
for( l = irc->users; l; l = l->next )
{
irc_user_t *iu = l->data;
bee_user_t *bu = iu->bu;
- if( !bu || ( bu->flags & ( BEE_USER_ONLINE | BEE_USER_AWAY ) ) != BEE_USER_ONLINE )
+ if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ||
+ ( bu->flags & ( BEE_USER_ONLINE | BEE_USER_AWAY ) ) != BEE_USER_ONLINE )
continue;
if( online == 1 )
@@ -1034,7 +1038,8 @@ static void cmd_blist( irc_t *irc, char **cmd )
irc_user_t *iu = l->data;
bee_user_t *bu = iu->bu;
- if( !bu || !( bu->flags & BEE_USER_ONLINE ) || !( bu->flags & BEE_USER_AWAY ) )
+ if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ||
+ !( bu->flags & BEE_USER_ONLINE ) || !( bu->flags & BEE_USER_AWAY ) )
continue;
if( away == 1 )
@@ -1050,7 +1055,8 @@ static void cmd_blist( irc_t *irc, char **cmd )
irc_user_t *iu = l->data;
bee_user_t *bu = iu->bu;
- if( !bu || bu->flags & BEE_USER_ONLINE )
+ if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ||
+ bu->flags & BEE_USER_ONLINE )
continue;
if( offline == 1 )
diff --git a/sock.h b/sock.h
index 848dc466..66e28987 100644
--- a/sock.h
+++ b/sock.h
@@ -12,6 +12,8 @@
#define sockerr_again() (errno == EINPROGRESS || errno == EINTR)
#ifndef EVENTS_LIBEVENT
#define closesocket(a) close(a)
+#else
+void closesocket( int fd );
#endif
#else
# include <winsock2.h>