diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-08-14 14:44:35 +0100 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-08-14 14:44:35 +0100 |
commit | 07874bef9e9c4e6ace44e4d0605ce1aec89cad74 (patch) | |
tree | c2a0a0bc30f2fcec7af83b2fb3fe59bbec393116 | |
parent | 584867592546f43f857645e02169d135f0df25e8 (diff) | |
parent | 136c2bb632715ab83710c93c7b339c5cca7d2679 (diff) |
Merge mainline stuff.
-rw-r--r-- | doc/user-guide/commands.xml | 4 | ||||
-rw-r--r-- | irc.h | 1 | ||||
-rw-r--r-- | irc_channel.c | 25 | ||||
-rw-r--r-- | irc_im.c | 16 | ||||
-rw-r--r-- | irc_send.c | 7 | ||||
-rw-r--r-- | irc_user.c | 6 | ||||
-rw-r--r-- | lib/misc.c | 80 | ||||
-rw-r--r-- | lib/misc.h | 3 | ||||
-rw-r--r-- | protocols/jabber/jabber.c | 18 | ||||
-rw-r--r-- | protocols/twitter/twitter.c | 2 | ||||
-rw-r--r-- | protocols/twitter/twitter_lib.c | 7 | ||||
-rw-r--r-- | root_commands.c | 12 | ||||
-rw-r--r-- | sock.h | 2 |
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> @@ -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; @@ -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 ) ) @@ -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 ); } @@ -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 ); @@ -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. */ @@ -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 ) @@ -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> |