From a0d04d6253cf70877a11156059209e1f9a2efe31 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 7 May 2006 20:07:43 +0200 Subject: Got rid of all GLib GIOChannel-related calls outside proxy.c --- irc.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 44fc9ad3..53dea8ba 100644 --- a/irc.c +++ b/irc.c @@ -53,15 +53,9 @@ irc_t *irc_new( int fd ) irc = g_new0( irc_t, 1 ); irc->fd = fd; - irc->io_channel = g_io_channel_unix_new( fd ); -#ifdef GLIB2 - g_io_channel_set_encoding (irc->io_channel, NULL, NULL); - g_io_channel_set_buffered (irc->io_channel, FALSE); - g_io_channel_set_flags( irc->io_channel, G_IO_FLAG_NONBLOCK, NULL ); -#else - fcntl( irc->fd, F_SETFL, O_NONBLOCK); -#endif - irc->r_watch_source_id = g_io_add_watch( irc->io_channel, G_IO_IN | G_IO_ERR | G_IO_HUP, bitlbee_io_current_client_read, irc ); + sock_make_nonblocking( irc->fd ); + + irc->r_watch_source_id = gaim_input_add( irc->fd, GAIM_INPUT_READ, bitlbee_io_current_client_read, irc ); irc->status = USTATUS_OFFLINE; irc->last_pong = gettime(); @@ -228,7 +222,6 @@ void irc_free(irc_t * irc) if( irc->w_watch_source_id > 0 ) g_source_remove( irc->w_watch_source_id ); - g_io_channel_unref( irc->io_channel ); irc_connection_list = g_slist_remove( irc_connection_list, irc ); for (account = irc->accounts; account; account = account->next) { @@ -599,19 +592,20 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) } strcat( line, "\r\n" ); - if( irc->sendbuffer != NULL ) { + if( irc->sendbuffer != NULL ) + { size = strlen( irc->sendbuffer ) + strlen( line ); irc->sendbuffer = g_renew ( char, irc->sendbuffer, size + 1 ); strcpy( ( irc->sendbuffer + strlen( irc->sendbuffer ) ), line ); } - else - irc->sendbuffer = g_strdup(line); - - if( irc->w_watch_source_id == 0 ) + else { - irc->w_watch_source_id = g_io_add_watch( irc->io_channel, G_IO_OUT, bitlbee_io_current_client_write, irc ); + irc->sendbuffer = g_strdup(line); } + if( irc->w_watch_source_id == 0 ) + irc->w_watch_source_id = gaim_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); + return; } @@ -635,7 +629,7 @@ void irc_write_all( int now, char *format, ... ) irc_vawrite( temp->data, format, params ); if( now ) { - bitlbee_io_current_client_write( irc->io_channel, G_IO_OUT, irc ); + bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ); } temp = temp->next; } -- cgit v1.2.3 From ba9edaa568088900145bbd1004c864b7d408c38d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 10 May 2006 19:34:46 +0200 Subject: Moved everything to the BitlBee event handling API. --- irc.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 53dea8ba..8112a3e8 100644 --- a/irc.c +++ b/irc.c @@ -28,7 +28,7 @@ #include "crypting.h" #include "ipc.h" -static gboolean irc_userping( gpointer _irc ); +static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); GSList *irc_connection_list = NULL; @@ -55,7 +55,7 @@ irc_t *irc_new( int fd ) irc->fd = fd; sock_make_nonblocking( irc->fd ); - irc->r_watch_source_id = gaim_input_add( irc->fd, GAIM_INPUT_READ, bitlbee_io_current_client_read, irc ); + irc->r_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_READ, bitlbee_io_current_client_read, irc ); irc->status = USTATUS_OFFLINE; irc->last_pong = gettime(); @@ -113,7 +113,7 @@ irc_t *irc_new( int fd ) if( !irc->myhost ) irc->myhost = g_strdup( "localhost." ); if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) - irc->ping_source_id = g_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); + irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" ); @@ -183,8 +183,8 @@ void irc_abort( irc_t *irc, int immed, char *format, ... ) to it that should shut down the connection in a second, just in case bitlbee_.._write doesn't do it first. */ - g_source_remove( irc->r_watch_source_id ); - irc->r_watch_source_id = g_timeout_add_full( G_PRIORITY_HIGH, 1000, (GSourceFunc) irc_free, irc, NULL ); + b_event_remove( irc->r_watch_source_id ); + irc->r_watch_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc ); } else { @@ -217,10 +217,10 @@ void irc_free(irc_t * irc) closesocket( irc->fd ); if( irc->ping_source_id > 0 ) - g_source_remove( irc->ping_source_id ); - g_source_remove( irc->r_watch_source_id ); + b_event_remove( irc->ping_source_id ); + b_event_remove( irc->r_watch_source_id ); if( irc->w_watch_source_id > 0 ) - g_source_remove( irc->w_watch_source_id ); + b_event_remove( irc->w_watch_source_id ); irc_connection_list = g_slist_remove( irc_connection_list, irc ); @@ -271,7 +271,7 @@ void irc_free(irc_t * irc) if(user->user!=user->nick) g_free(user->user); if(user->host!=user->nick) g_free(user->host); if(user->realname!=user->nick) g_free(user->realname); - gaim_input_remove(user->sendbuf_timer); + b_event_remove(user->sendbuf_timer); usertmp = user; user = user->next; @@ -321,7 +321,7 @@ void irc_free(irc_t * irc) g_free(irc); if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) - g_main_quit( global.loop ); + b_main_quit(); } /* USE WITH CAUTION! @@ -604,7 +604,7 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) } if( irc->w_watch_source_id == 0 ) - irc->w_watch_source_id = gaim_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); + irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); return; } @@ -1010,7 +1010,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) return( 0 ); } -gboolean buddy_send_handler_delayed( gpointer data ) +static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_condition cond ) { user_t *u = data; @@ -1023,7 +1023,7 @@ gboolean buddy_send_handler_delayed( gpointer data ) u->sendbuf_timer = 0; u->sendbuf_flags = 0; - return( FALSE ); + return FALSE; } void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) @@ -1037,8 +1037,8 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) if( u->sendbuf_len > 0 && u->sendbuf_flags != flags) { //Flush the buffer - g_source_remove( u->sendbuf_timer ); - buddy_send_handler_delayed( u ); + b_event_remove( u->sendbuf_timer ); + buddy_send_handler_delayed( u, -1, 0 ); } if( u->sendbuf_len == 0 ) @@ -1062,8 +1062,8 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) delay *= 1000; if( u->sendbuf_timer > 0 ) - g_source_remove( u->sendbuf_timer ); - u->sendbuf_timer = g_timeout_add( delay, buddy_send_handler_delayed, u ); + b_event_remove( u->sendbuf_timer ); + u->sendbuf_timer = b_timeout_add( delay, buddy_send_handler_delayed, u ); } else { @@ -1147,7 +1147,7 @@ int irc_noticefrom( irc_t *irc, char *nick, char *msg ) timeout. The number returned is the number of seconds we received no pongs from the user. When not connected yet, we don't ping but drop the connection when the user fails to connect in IRC_LOGIN_TIMEOUT secs. */ -static gboolean irc_userping( gpointer _irc ) +static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond ) { irc_t *irc = _irc; int rv = 0; -- cgit v1.2.3 From 0356ae3aa10bb6556d0ea881988831cad5e71f38 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 May 2006 00:30:51 +0200 Subject: irc_vawrite() now first attempts to write() immediately (because that's usually not a problem) and only touches the event queue when the write() doesn't write everything. And got rid of a quit element in the irc_t structure that actually wasn't even used. --- irc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 8112a3e8..6ae0e108 100644 --- a/irc.c +++ b/irc.c @@ -575,7 +575,8 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) int size; char line[IRC_MAX_LINE+1], *cs; - if( irc->quit ) + /* Don't try to write anything new anymore when shutting down. */ + if( irc->status == USTATUS_SHUTDOWN ) return; line[IRC_MAX_LINE] = 0; @@ -604,7 +605,14 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) } if( irc->w_watch_source_id == 0 ) - irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); + { + /* If the buffer is empty we can probably write, so call the write event handler + immediately. If it returns TRUE, it should be called again, so add the event to + the queue. If it's FALSE, we emptied the buffer and saved ourselves some work + in the event queue. */ + if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) + irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); + } return; } -- cgit v1.2.3 From 574af7e01a0cc738b4bbe7e903572943a85b9691 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 26 May 2006 01:20:54 +0200 Subject: Require GLib 2 --- irc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index fb85de62..db9f7aad 100644 --- a/irc.c +++ b/irc.c @@ -54,13 +54,9 @@ irc_t *irc_new( int fd ) irc->fd = fd; irc->io_channel = g_io_channel_unix_new( fd ); -#ifdef GLIB2 g_io_channel_set_encoding (irc->io_channel, NULL, NULL); g_io_channel_set_buffered (irc->io_channel, FALSE); g_io_channel_set_flags( irc->io_channel, G_IO_FLAG_NONBLOCK, NULL ); -#else - fcntl( irc->fd, F_SETFL, O_NONBLOCK); -#endif irc->r_watch_source_id = g_io_add_watch( irc->io_channel, G_IO_IN | G_IO_ERR | G_IO_HUP, bitlbee_io_current_client_read, irc ); irc->status = USTATUS_OFFLINE; -- cgit v1.2.3 From fb62f81f947c74e274b05e32d2e88e3a4d7e2613 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 3 Jun 2006 21:51:16 +0200 Subject: Implemented netsplits for "account off". --- irc.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index db9f7aad..3d3baca6 100644 --- a/irc.c +++ b/irc.c @@ -898,9 +898,31 @@ void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker ) void irc_kill( irc_t *irc, user_t *u ) { - char *nick; + char *nick, *s; + char reason[64]; + + if( u->gc && u->gc->flags & OPT_LOGGING_OUT ) + { + if( u->gc->user->proto_opt[0][0] ) + g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, + u->gc->user->proto_opt[0] ); + else if( ( s = strchr( u->gc->username, '@' ) ) ) + g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, + s + 1 ); + else + g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost, + u->gc->prpl->name, irc->myhost ); + + /* proto_opt might contain garbage after the : */ + if( ( s = strchr( reason, ':' ) ) ) + *s = 0; + } + else + { + strcpy( reason, "Leaving..." ); + } - irc_write( irc, ":%s!%s@%s QUIT :%s", u->nick, u->user, u->host, "Leaving..." ); + irc_write( irc, ":%s!%s@%s QUIT :%s", u->nick, u->user, u->host, reason ); nick = g_strdup( u->nick ); nick_lc( nick ); -- cgit v1.2.3 From 79e826a028f4b4c62c0c16e20af1fb13a9636324 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 15 Jun 2006 14:22:17 +0200 Subject: Converted irc->status to binary flags. (This also fixes auto-save-on-quit that broke because of USTATUS_SHUTDOWN. :-( ) --- irc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 3d3baca6..cd30d1c2 100644 --- a/irc.c +++ b/irc.c @@ -178,7 +178,7 @@ void irc_abort( irc_t *irc, int immed, char *format, ... ) irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" ); } - irc->status = USTATUS_SHUTDOWN; + irc->status |= USTATUS_SHUTDOWN; if( irc->sendbuffer && !immed ) { /* We won't read from this socket anymore. Instead, we'll connect a timer @@ -212,7 +212,7 @@ void irc_free(irc_t * irc) log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); - if( irc->status >= USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) + if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) if( storage_save( irc, TRUE ) != STORAGE_OK ) irc_usermsg( irc, "Error while saving settings!" ); @@ -700,7 +700,7 @@ int irc_check_login( irc_t *irc ) { if( irc->user && irc->nick ) { - if( global.conf->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED ) + if( global.conf->authmode == AUTHMODE_CLOSED && ! irc->status & USTATUS_AUTHORIZED ) { irc_reply( irc, 464, ":This server is password-protected." ); return 0; @@ -757,7 +757,7 @@ void irc_login( irc_t *irc ) if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); - irc->status = USTATUS_LOGGED_IN; + irc->status |= USTATUS_LOGGED_IN; } void irc_motd( irc_t *irc ) @@ -1180,7 +1180,7 @@ static gboolean irc_userping( gpointer _irc ) irc_t *irc = _irc; int rv = 0; - if( irc->status < USTATUS_LOGGED_IN ) + if( ! irc->status & USTATUS_LOGGED_IN ) { if( gettime() > ( irc->last_pong + IRC_LOGIN_TIMEOUT ) ) rv = gettime() - irc->last_pong; -- cgit v1.2.3 From 3af70b06b2f0fb0fb41a041f6d86e3711b9eea3f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 15 Jun 2006 14:37:05 +0200 Subject: !x&y == (!x)&y, not !(x&y). --- irc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index cd30d1c2..62af4b08 100644 --- a/irc.c +++ b/irc.c @@ -700,7 +700,7 @@ int irc_check_login( irc_t *irc ) { if( irc->user && irc->nick ) { - if( global.conf->authmode == AUTHMODE_CLOSED && ! irc->status & USTATUS_AUTHORIZED ) + if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) ) { irc_reply( irc, 464, ":This server is password-protected." ); return 0; @@ -1180,7 +1180,7 @@ static gboolean irc_userping( gpointer _irc ) irc_t *irc = _irc; int rv = 0; - if( ! irc->status & USTATUS_LOGGED_IN ) + if( !( irc->status & USTATUS_LOGGED_IN ) ) { if( gettime() > ( irc->last_pong + IRC_LOGIN_TIMEOUT ) ) rv = gettime() - irc->last_pong; -- cgit v1.2.3 From 6e1fed7057ee26f21b0e59a5aeb292d4f3f0e8ae Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 25 Jun 2006 19:07:25 +0200 Subject: Using salted MD5 checksums for the user's BitlBee password and salted RC4 encryption for the IM account passwords, plus some calls to srand() to keep the salts secure and unique. --- irc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index c045d12b..b5751859 100644 --- a/irc.c +++ b/irc.c @@ -328,11 +328,10 @@ void irc_free(irc_t * irc) Sets pass without checking */ void irc_setpass (irc_t *irc, const char *pass) { - if (irc->password) g_free (irc->password); + g_free (irc->password); if (pass) { irc->password = g_strdup (pass); - irc_usermsg (irc, "Password successfully changed"); } else { irc->password = NULL; } -- cgit v1.2.3 From 88086dbd9002123be39d00c53460f1ec9f2b719a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 25 Jun 2006 19:23:27 +0200 Subject: Added versioning information to the XML-file (convenient for later format changes), got rid of confusing "Password successfully changed" message when the user uses the identify-command and protected rc4_decode() against short inputs. --- irc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index b5751859..c07a3ea3 100644 --- a/irc.c +++ b/irc.c @@ -32,10 +32,11 @@ static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); GSList *irc_connection_list = NULL; -static char *passchange (irc_t *irc, void *set, char *value) +static char *passchange( irc_t *irc, void *set, char *value ) { - irc_setpass (irc, value); - return (NULL); + irc_setpass( irc, value ); + irc_usermsg( irc, "Password successfully changed" ); + return NULL; } irc_t *irc_new( int fd ) -- cgit v1.2.3 From 9b63df67847e72abb00246fdfc82830137153c3c Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 25 Jun 2006 21:20:14 +0200 Subject: Why did I forget this one? *sigh* --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 52b80d41..c045d12b 100644 --- a/irc.c +++ b/irc.c @@ -576,7 +576,7 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) char line[IRC_MAX_LINE+1], *cs; /* Don't try to write anything new anymore when shutting down. */ - if( irc->status == USTATUS_SHUTDOWN ) + if( irc->status & USTATUS_SHUTDOWN ) return; line[IRC_MAX_LINE] = 0; -- cgit v1.2.3 From 2f1322291d06a3a401f730802d501ea3cae6f4e3 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 25 Jun 2006 21:55:18 +0200 Subject: IRC protocol compliance fixes (closes: #158, #159, #160). --- irc.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index c045d12b..5f69b2ea 100644 --- a/irc.c +++ b/irc.c @@ -656,7 +656,7 @@ void irc_names( irc_t *irc, char *channel ) if( !control ) c = conv_findchannel( channel ); - /* RFC's say there is no error reply allowed on NAMES, so when the + /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ if( control || c ) while( u ) @@ -670,7 +670,7 @@ void irc_names( irc_t *irc, char *channel ) else s = ""; - irc_reply( irc, 353, "@ %s :%s%s", channel, s, u->nick ); + irc_reply( irc, 353, "= %s :%s%s", channel, s, u->nick ); } else if( !u->gc ) { @@ -681,7 +681,7 @@ void irc_names( irc_t *irc, char *channel ) else s = ""; - irc_reply( irc, 353, "@ %s :%s%s", channel, s, u->nick ); + irc_reply( irc, 353, "= %s :%s%s", channel, s, u->nick ); } } @@ -696,7 +696,7 @@ void irc_names( irc_t *irc, char *channel ) for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->gc, l->data ) ) ) - irc_reply( irc, 353, "@ %s :%s%s", channel, "", u->nick ); + irc_reply( irc, 353, "= %s :%s%s", channel, "", u->nick ); } irc_reply( irc, 366, "%s :End of /NAMES list", channel ); @@ -734,6 +734,7 @@ void irc_login( irc_t *irc ) irc_reply( irc, 4, "%s %s %s %s", irc->myhost, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES ); irc_reply( irc, 5, "PREFIX=(ov)@+ CHANTYPES=#& CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server", CMODES, MAX_NICK_LENGTH - 1 ); irc_motd( irc ); + irc->umode[0] = '\0'; irc_umode_set( irc, "+" UMODE, 1 ); u = user_add( irc, irc->mynick ); @@ -841,19 +842,33 @@ void irc_umode_set( irc_t *irc, char *s, int allow_priv ) to set a "privileged" mode (+o, +R, etc). */ char m[256], st = 1, *t; int i; + char changes[512], *p, st2 = 2; + char badflag = 0; memset( m, 0, sizeof( m ) ); for( t = irc->umode; *t; t ++ ) m[(int)*t] = 1; - + + p = changes; for( t = s; *t; t ++ ) { if( *t == '+' || *t == '-' ) st = *t == '+'; else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) ) + { + if( m[(int)*t] != st) + { + if( st != st2 ) + st2 = st, *p++ = st ? '+' : '-'; + *p++ = *t; + } m[(int)*t] = st; + } + else + badflag = 1; } + *p = '\0'; memset( irc->umode, 0, sizeof( irc->umode ) ); @@ -861,7 +876,11 @@ void irc_umode_set( irc_t *irc, char *s, int allow_priv ) if( m[i] ) irc->umode[strlen(irc->umode)] = i; - irc_reply( irc, 221, "+%s", irc->umode ); + if( badflag ) + irc_reply( irc, 501, ":Unknown MODE flag" ); + /* Deliberately no !user@host on the prefix here */ + if( *changes ) + irc_write( irc, ":%s MODE %s %s", irc->nick, irc->nick, changes ); } void irc_spawn( irc_t *irc, user_t *u ) -- cgit v1.2.3 From 3f9440db856c1b1cde54eb919543cfc23ea09983 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 26 Jun 2006 23:50:12 +0200 Subject: /NAMES replies are more efficient now. --- irc.c | 69 +++++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 5f69b2ea..816b69d9 100644 --- a/irc.c +++ b/irc.c @@ -648,57 +648,56 @@ void irc_write_all( int now, char *format, ... ) void irc_names( irc_t *irc, char *channel ) { - user_t *u = irc->users; - char *s; - int control = ( g_strcasecmp( channel, irc->channel ) == 0 ); + user_t *u; + char namelist[385] = ""; struct conversation *c = NULL; - if( !control ) - c = conv_findchannel( channel ); - /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ - if( control || c ) while( u ) + if( g_strcasecmp( channel, irc->channel ) == 0 ) { - if( u->online ) + for( u = irc->users; u; u = u->next ) if( u->online ) { - if( u->gc && control ) + if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 ) { - if( set_getint( irc, "away_devoice" ) && !u->away ) - s = "+"; - else - s = ""; - - irc_reply( irc, 353, "= %s :%s%s", channel, s, u->nick ); - } - else if( !u->gc ) - { - if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "root" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) ) - s = "@"; - else if( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "user" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) ) - s = "@"; - else - s = ""; - - irc_reply( irc, 353, "= %s :%s%s", channel, s, u->nick ); + irc_reply( irc, 353, "= %s :%s", channel, namelist ); + *namelist = 0; } + + if( u->gc && !u->away && set_getint( irc, "away_devoice" ) ) + strcat( namelist, "+" ); + + strcat( namelist, u->nick ); + strcat( namelist, " " ); } - - u = u->next; } - - /* For non-controlchannel channels (group conversations) only root and - you are listed now. Time to show the channel people: */ - if( !control && c ) + else if( ( c = conv_findchannel( channel ) ) ) { GList *l; + char *ops = set_getstr( irc, "ops" ); - for( l = c->in_room; l; l = l->next ) - if( ( u = user_findhandle( c->gc, l->data ) ) ) - irc_reply( irc, 353, "= %s :%s%s", channel, "", u->nick ); + /* root and the user aren't in the channel userlist but should + show up in /NAMES, so list them first: */ + sprintf( namelist, "%s%s %s%s ", strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->mynick, + strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->nick ); + + for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->gc, l->data ) ) ) + { + if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 ) + { + irc_reply( irc, 353, "= %s :%s", channel, namelist ); + *namelist = 0; + } + + strcat( namelist, u->nick ); + strcat( namelist, " " ); + } } + if( *namelist ) + irc_reply( irc, 353, "= %s :%s", channel, namelist ); + irc_reply( irc, 366, "%s :End of /NAMES list", channel ); } -- cgit v1.2.3 From 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 30 Jun 2006 11:17:18 +0200 Subject: Made set.c API more generic so it's not specific to irc_t structures anymore, but can be used for account_t structures too, for example. --- irc.c | 58 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index f6e7cbb7..60769735 100644 --- a/irc.c +++ b/irc.c @@ -120,26 +120,26 @@ irc_t *irc_new( int fd ) irc_connection_list = g_slist_append( irc_connection_list, irc ); - set_add( irc, "away_devoice", "true", set_eval_away_devoice ); - set_add( irc, "auto_connect", "true", set_eval_bool ); - set_add( irc, "auto_reconnect", "false", set_eval_bool ); - set_add( irc, "auto_reconnect_delay", "300", set_eval_int ); - set_add( irc, "buddy_sendbuffer", "false", set_eval_bool ); - set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int ); - set_add( irc, "charset", "iso8859-1", set_eval_charset ); - set_add( irc, "debug", "false", set_eval_bool ); - set_add( irc, "default_target", "root", NULL ); - set_add( irc, "display_namechanges", "false", set_eval_bool ); - set_add( irc, "handle_unknown", "root", NULL ); - set_add( irc, "lcnicks", "true", set_eval_bool ); - set_add( irc, "ops", "both", set_eval_ops ); - set_add( irc, "private", "true", set_eval_bool ); - set_add( irc, "query_order", "lifo", NULL ); - set_add( irc, "save_on_quit", "true", set_eval_bool ); - set_add( irc, "strip_html", "true", NULL ); - set_add( irc, "to_char", ": ", set_eval_to_char ); - set_add( irc, "typing_notice", "false", set_eval_bool ); - set_add( irc, "password", NULL, passchange); + set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); + set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); + set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); + set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc ); + set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); + set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); + set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc ); + set_add( &irc->set, "debug", "false", set_eval_bool, irc ); + set_add( &irc->set, "default_target", "root", NULL, irc ); + set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); + set_add( &irc->set, "handle_unknown", "root", NULL, irc ); + set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); + set_add( &irc->set, "ops", "both", set_eval_ops, irc ); + set_add( &irc->set, "password", NULL, passchange, irc ); + set_add( &irc->set, "private", "true", set_eval_bool, irc ); + set_add( &irc->set, "query_order", "lifo", NULL, irc ); + set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); + set_add( &irc->set, "strip_html", "true", NULL, irc ); + set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); + set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); conf_loaddefaults( irc ); @@ -211,7 +211,7 @@ void irc_free(irc_t * irc) log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); - if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) + if( irc->status & USTATUS_IDENTIFIED && set_getint( &irc->set, "save_on_quit" ) ) if( storage_save( irc, TRUE ) != STORAGE_OK ) irc_usermsg( irc, "Error while saving settings!" ); @@ -363,7 +363,7 @@ void irc_process( irc_t *irc ) break; } - if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) + if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) { conv[IRC_MAX_LINE] = 0; if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) != -1 ) @@ -583,7 +583,7 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); strip_newlines( line ); - if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) + if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) { char conv[IRC_MAX_LINE+1]; @@ -665,7 +665,7 @@ void irc_names( irc_t *irc, char *channel ) { if( u->gc && control ) { - if( set_getint( irc, "away_devoice" ) && !u->away ) + if( set_getint( &irc->set, "away_devoice" ) && !u->away ) s = "+"; else s = ""; @@ -674,9 +674,9 @@ void irc_names( irc_t *irc, char *channel ) } else if( !u->gc ) { - if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "root" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) ) + if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( &irc->set, "ops" ), "root" ) == 0 || strcmp( set_getstr( &irc->set, "ops" ), "both" ) == 0 ) ) s = "@"; - else if( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "user" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) ) + else if( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( set_getstr( &irc->set, "ops" ), "user" ) == 0 || strcmp( set_getstr( &irc->set, "ops" ), "both" ) == 0 ) ) s = "@"; else s = ""; @@ -1083,7 +1083,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) { if( !u || !u->gc ) return; - if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 ) + if( set_getint( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) { int delay; @@ -1110,7 +1110,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) strcat( u->sendbuf, msg ); strcat( u->sendbuf, "\n" ); - delay = set_getint( irc, "buddy_sendbuffer_delay" ); + delay = set_getint( &irc->set, "buddy_sendbuffer_delay" ); if( delay <= 5 ) delay *= 1000; @@ -1175,7 +1175,7 @@ int irc_msgfrom( irc_t *irc, char *nick, char *msg ) { int len = strlen( irc->nick) + 3; prefix = g_new (char, len ); - g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) ); + g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) ); prefix[len-1] = 0; } else -- cgit v1.2.3 From 0a3c243b6659dc10efb227e507f324c2711d6dcd Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 1 Jul 2006 01:18:56 +0200 Subject: Got rid of struct aim_user (now using account_t everywhere). Needs some more testing though. --- irc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 60769735..d93fbe44 100644 --- a/irc.c +++ b/irc.c @@ -924,19 +924,19 @@ void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker ) void irc_kill( irc_t *irc, user_t *u ) { char *nick, *s; - char reason[64]; + char reason[128]; if( u->gc && u->gc->flags & OPT_LOGGING_OUT ) { - if( u->gc->user->proto_opt[0][0] ) + if( u->gc->acc->server ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, - u->gc->user->proto_opt[0] ); + u->gc->acc->server ); else if( ( s = strchr( u->gc->username, '@' ) ) ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, s + 1 ); else g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost, - u->gc->prpl->name, irc->myhost ); + u->gc->acc->prpl->name, irc->myhost ); /* proto_opt might contain garbage after the : */ if( ( s = strchr( reason, ':' ) ) ) @@ -1012,13 +1012,13 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) } else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 ) { - if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 ) + if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 ) { time_t current_typing_notice = time( NULL ); if( current_typing_notice - u->last_typing_notice >= 5 ) { - u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' ); + u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' ); u->last_typing_notice = current_typing_notice; } } @@ -1051,7 +1051,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) return 1; } } - else if( c && c->gc && c->gc->prpl ) + else if( c && c->gc && c->gc->acc && c->gc->acc->prpl ) { return( bim_chat_msg( c->gc, c->id, s ) ); } -- cgit v1.2.3 From 5b52a4895e5a59ff6509f7771f4d8665737688c3 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 3 Jul 2006 23:22:45 +0200 Subject: Implemented per-account nick lists instead of per-protocol nick lists. nick_t is dead, instead nicks are just saves in a per-account_t GLib hash table. While doing this, the import_buddies command finally died and text_save() disappeared, because the old file format can't handle most of the new features in this branch anyway. Still have to implement support for the new nick lists in text_load()! --- irc.c | 43 ++++++------------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index bac91198..fe55a02c 100644 --- a/irc.c +++ b/irc.c @@ -203,11 +203,9 @@ static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ) /* Because we have no garbage collection, this is quite annoying */ void irc_free(irc_t * irc) { - account_t *account, *accounttmp; + account_t *account; user_t *user, *usertmp; - nick_t *nick, *nicktmp; help_t *helpnode, *helpnodetmp; - set_t *setnode, *setnodetmp; log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); @@ -251,17 +249,11 @@ void irc_free(irc_t * irc) while (irc->queries != NULL) query_del(irc, irc->queries); - if (irc->accounts != NULL) { - account = irc->accounts; - while (account != NULL) { - g_free(account->user); - g_free(account->pass); - g_free(account->server); - accounttmp = account; - account = account->next; - g_free(accounttmp); - } - } + while (irc->accounts) + account_del(irc, irc->accounts); + + while (irc->set) + set_del(&irc->set, irc->set->key); if (irc->users != NULL) { user = irc->users; @@ -286,17 +278,6 @@ void irc_free(irc_t * irc) g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); g_hash_table_destroy(irc->watches); - if (irc->nicks != NULL) { - nick = irc->nicks; - while (nick != NULL) { - g_free(nick->nick); - g_free(nick->handle); - - nicktmp = nick; - nick = nick->next; - g_free(nicktmp); - } - } if (irc->help != NULL) { helpnode = irc->help; while (helpnode != NULL) { @@ -307,18 +288,6 @@ void irc_free(irc_t * irc) g_free(helpnodetmp); } } - if (irc->set != NULL) { - setnode = irc->set; - while (setnode != NULL) { - g_free(setnode->key); - g_free(setnode->def); - g_free(setnode->value); - - setnodetmp = setnode; - setnode = setnode->next; - g_free(setnodetmp); - } - } g_free(irc); if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) -- cgit v1.2.3 From a93e3c822a697562c2e05906059922ed28f51ca5 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 9 Jul 2006 12:54:45 +0200 Subject: Fixed irc_names() (forgot to add @s for user/root in the new version). --- irc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 816b69d9..1a7579b8 100644 --- a/irc.c +++ b/irc.c @@ -651,6 +651,7 @@ void irc_names( irc_t *irc, char *channel ) user_t *u; char namelist[385] = ""; struct conversation *c = NULL; + char *ops = set_getstr( irc, "ops" ); /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ @@ -667,6 +668,9 @@ void irc_names( irc_t *irc, char *channel ) if( u->gc && !u->away && set_getint( irc, "away_devoice" ) ) strcat( namelist, "+" ); + else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || + ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) + strcat( namelist, "@" ); strcat( namelist, u->nick ); strcat( namelist, " " ); @@ -675,7 +679,6 @@ void irc_names( irc_t *irc, char *channel ) else if( ( c = conv_findchannel( channel ) ) ) { GList *l; - char *ops = set_getstr( irc, "ops" ); /* root and the user aren't in the channel userlist but should show up in /NAMES, so list them first: */ -- cgit v1.2.3 From b0a33a50735d93e1414a2e6c2007884d756429a3 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 11 Jul 2006 11:28:44 +0200 Subject: Better handling of situations where IPv6 is not available at run-time. --- irc.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 1a7579b8..53ca7c4c 100644 --- a/irc.c +++ b/irc.c @@ -45,10 +45,10 @@ irc_t *irc_new( int fd ) unsigned int i; char buf[128]; #ifdef IPV6 - struct sockaddr_in6 sock[1]; -#else - struct sockaddr_in sock[1]; + struct sockaddr_in6 sock6[1]; + unsigned int i6; #endif + struct sockaddr_in sock[1]; irc = g_new0( irc_t, 1 ); @@ -68,45 +68,48 @@ irc_t *irc_new( int fd ) irc->channel = g_strdup( ROOT_CHAN ); i = sizeof( *sock ); +#ifdef IPV6 + i6 = sizeof( *sock6 ); +#endif if( global.conf->hostname ) irc->myhost = g_strdup( global.conf->hostname ); #ifdef IPV6 - else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx ) + else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) irc->myhost = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->myhost = g_strdup( ipv6_unwrap( buf ) ); } -#else - else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) +#endif + else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) irc->myhost = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->myhost = g_strdup( buf ); } -#endif i = sizeof( *sock ); #ifdef IPV6 - if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx ) + i6 = sizeof( *sock6 ); + if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) irc->host = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->host = g_strdup( ipv6_unwrap( buf ) ); } -#else - if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) + else +#endif + if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) irc->host = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->host = g_strdup( buf ); } -#endif /* Rare, but possible. */ if( !irc->host ) irc->host = g_strdup( "localhost." ); -- cgit v1.2.3 From 04026d44c29f2b7d64f81bb2d2d061a7d111662f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 15 Jul 2006 19:26:13 +0200 Subject: Fixed a broken call to set_get() (CRASH), shut up a compiler warning in events_glib and now using the right evaluator for acc->"auto_reconnect". --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 9feb9f4e..fcb59c86 100644 --- a/irc.c +++ b/irc.c @@ -623,7 +623,7 @@ void irc_names( irc_t *irc, char *channel ) user_t *u; char namelist[385] = ""; struct conversation *c = NULL; - char *ops = set_getstr( irc, "ops" ); + char *ops = set_getstr( &irc->set, "ops" ); /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ -- cgit v1.2.3 From 0aaca60fdc1a6793b438ecc926bd937073d22685 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 19 Jul 2006 18:52:38 +0200 Subject: Added some (more) comments to .h files in lib/ and some minor fixes/cleanups. --- irc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index fcb59c86..0373f176 100644 --- a/irc.c +++ b/irc.c @@ -651,7 +651,6 @@ void irc_names( irc_t *irc, char *channel ) else if( ( c = conv_findchannel( channel ) ) ) { GList *l; - char *ops = set_getstr( &irc->set, "ops" ); /* root and the user aren't in the channel userlist but should show up in /NAMES, so list them first: */ -- cgit v1.2.3 From d5ccd83c5235528df2481003502647b86b41fdc4 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 13 Aug 2006 21:15:23 +0200 Subject: Extra comments in set.h and now properly using set_getbool() instead of set_getint(). --- irc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 0373f176..87cc4c78 100644 --- a/irc.c +++ b/irc.c @@ -212,7 +212,7 @@ void irc_free(irc_t * irc) log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); - if( irc->status & USTATUS_IDENTIFIED && set_getint( &irc->set, "save_on_quit" ) ) + if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) if( storage_save( irc, TRUE ) != STORAGE_OK ) irc_usermsg( irc, "Error while saving settings!" ); @@ -1057,7 +1057,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) { if( !u || !u->gc ) return; - if( set_getint( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) + if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) { int delay; -- cgit v1.2.3 From 0383943c38ee308805798974bfccbd3327369c6a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 25 Aug 2006 00:06:52 +0200 Subject: Added message on successful creation of accounts and fixed "set password" command. --- irc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 87cc4c78..8f79b535 100644 --- a/irc.c +++ b/irc.c @@ -32,8 +32,10 @@ static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); GSList *irc_connection_list = NULL; -static char *passchange( irc_t *irc, void *set, char *value ) +static char *passchange( set_t *set, char *value ) { + irc_t *irc = set->data; + irc_setpass( irc, value ); irc_usermsg( irc, "Password successfully changed" ); return NULL; -- cgit v1.2.3 From bbb6ffb4d2f4e02d3f856f731a83cb6b911bf659 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 31 Oct 2006 09:35:36 +0100 Subject: Disabling little optimization in irc.c because it can't be done safely in this part of the code for now. --- irc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 8f79b535..f9654034 100644 --- a/irc.c +++ b/irc.c @@ -584,8 +584,11 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) immediately. If it returns TRUE, it should be called again, so add the event to the queue. If it's FALSE, we emptied the buffer and saved ourselves some work in the event queue. */ - if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) - irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); + /* Really can't be done as long as the code doesn't do error checking very well: + if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) */ + + /* So just always do it via the event handler. */ + irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); } return; -- cgit v1.2.3 From f959495182db79b0c3b51c6bc4e9fcacdc591c40 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 18 Feb 2007 17:19:01 +0000 Subject: Preventing infinite loop while cleaning up accounts in irc_free(). Closes #245. --- irc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index f9654034..eb4a395d 100644 --- a/irc.c +++ b/irc.c @@ -255,7 +255,12 @@ void irc_free(irc_t * irc) query_del(irc, irc->queries); while (irc->accounts) - account_del(irc, irc->accounts); + if (irc->accounts->gc == NULL) + account_del(irc, irc->accounts); + else + /* Nasty hack, but account_del() doesn't work in this + case and we don't want infinite loops, do we? ;-) */ + irc->accounts = irc->accounts->next; while (irc->set) set_del(&irc->set, irc->set->key); -- cgit v1.2.3 From fa29d09342c79b886efacee4cfc3078be5f5a722 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 27 Mar 2007 22:53:11 -0700 Subject: Preparing for Jabber conference room support. --- irc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index eb4a395d..5551f559 100644 --- a/irc.c +++ b/irc.c @@ -658,7 +658,7 @@ void irc_names( irc_t *irc, char *channel ) strcat( namelist, " " ); } } - else if( ( c = conv_findchannel( channel ) ) ) + else if( ( c = chat_by_channel( channel ) ) ) { GList *l; @@ -811,7 +811,7 @@ void irc_topic( irc_t *irc, char *channel ) } else { - struct conversation *c = conv_findchannel( channel ); + struct conversation *c = chat_by_channel( channel ); if( c ) irc_reply( irc, 332, "%s :BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", channel, c->title ); @@ -949,7 +949,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) if( *nick == '#' || *nick == '&' ) { - if( !( c = conv_findchannel( nick ) ) ) + if( !( c = chat_by_channel( nick ) ) ) { irc_reply( irc, 403, "%s :Channel does not exist", nick ); return( 0 ); @@ -1037,7 +1037,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) } else if( c && c->gc && c->gc->acc && c->gc->acc->prpl ) { - return( bim_chat_msg( c->gc, c->id, s ) ); + return( bim_chat_msg( c, s ) ); } return( 0 ); -- cgit v1.2.3 From 0da65d5fb37691ed4d31f7ab4058732f1440db6b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 30 Mar 2007 22:40:45 -0700 Subject: s/gaim_connection/im_connection/ and some other minor API changes. The rest will come tomorrow. It compiles, I'll leave the real testing up to someone else. ;-) --- irc.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 5551f559..b1cae1d9 100644 --- a/irc.c +++ b/irc.c @@ -229,9 +229,9 @@ void irc_free(irc_t * irc) irc_connection_list = g_slist_remove( irc_connection_list, irc ); for (account = irc->accounts; account; account = account->next) { - if (account->gc) { - account->gc->wants_to_die = TRUE; - signoff(account->gc); + if (account->ic) { + account->ic->wants_to_die = TRUE; + signoff(account->ic); } else if (account->reconnect) { cancel_auto_reconnect(account); } @@ -255,7 +255,7 @@ void irc_free(irc_t * irc) query_del(irc, irc->queries); while (irc->accounts) - if (irc->accounts->gc == NULL) + if (irc->accounts->ic == NULL) account_del(irc, irc->accounts); else /* Nasty hack, but account_del() doesn't work in this @@ -632,7 +632,7 @@ void irc_names( irc_t *irc, char *channel ) { user_t *u; char namelist[385] = ""; - struct conversation *c = NULL; + struct groupchat *c = NULL; char *ops = set_getstr( &irc->set, "ops" ); /* RFCs say there is no error reply allowed on NAMES, so when the @@ -648,7 +648,7 @@ void irc_names( irc_t *irc, char *channel ) *namelist = 0; } - if( u->gc && !u->away && set_getbool( &irc->set, "away_devoice" ) ) + if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) ) strcat( namelist, "+" ); else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) @@ -667,7 +667,7 @@ void irc_names( irc_t *irc, char *channel ) sprintf( namelist, "%s%s %s%s ", strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->mynick, strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->nick ); - for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->gc, l->data ) ) ) + for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->ic, l->data ) ) ) { if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 ) { @@ -811,7 +811,7 @@ void irc_topic( irc_t *irc, char *channel ) } else { - struct conversation *c = chat_by_channel( channel ); + struct groupchat *c = chat_by_channel( channel ); if( c ) irc_reply( irc, 332, "%s :BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", channel, c->title ); @@ -910,17 +910,17 @@ void irc_kill( irc_t *irc, user_t *u ) char *nick, *s; char reason[128]; - if( u->gc && u->gc->flags & OPT_LOGGING_OUT ) + if( u->ic && u->ic->flags & OPT_LOGGING_OUT ) { - if( u->gc->acc->server ) + if( u->ic->acc->server ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, - u->gc->acc->server ); - else if( ( s = strchr( u->gc->username, '@' ) ) ) + u->ic->acc->server ); + else if( ( s = strchr( u->ic->username, '@' ) ) ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, s + 1 ); else g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost, - u->gc->acc->prpl->name, irc->myhost ); + u->ic->acc->prpl->name, irc->myhost ); /* proto_opt might contain garbage after the : */ if( ( s = strchr( reason, ':' ) ) ) @@ -944,7 +944,7 @@ void irc_kill( irc_t *irc, user_t *u ) int irc_send( irc_t *irc, char *nick, char *s, int flags ) { - struct conversation *c = NULL; + struct groupchat *c = NULL; user_t *u = NULL; if( *nick == '#' || *nick == '&' ) @@ -996,13 +996,13 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) } else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 ) { - if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 ) + if( u && u->ic && u->ic->acc->prpl->send_typing && strlen( s ) >= 10 ) { time_t current_typing_notice = time( NULL ); if( current_typing_notice - u->last_typing_notice >= 5 ) { - u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' ); + u->ic->acc->prpl->send_typing( u->ic, u->handle, s[8] == '1' ); u->last_typing_notice = current_typing_notice; } } @@ -1035,9 +1035,9 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) return 1; } } - else if( c && c->gc && c->gc->acc && c->gc->acc->prpl ) + else if( c && c->ic && c->ic->acc && c->ic->acc->prpl ) { - return( bim_chat_msg( c, s ) ); + return( bim_chat_msg( c, s, 0 ) ); } return( 0 ); @@ -1052,7 +1052,7 @@ static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_cond return FALSE; u->sendbuf[u->sendbuf_len-2] = 0; /* Cut off the last newline */ - bim_buddy_msg( u->gc, u->handle, u->sendbuf, u->sendbuf_flags ); + bim_buddy_msg( u->ic, u->handle, u->sendbuf, u->sendbuf_flags ); g_free( u->sendbuf ); u->sendbuf = NULL; @@ -1065,7 +1065,7 @@ static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_cond void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) { - if( !u || !u->gc ) return; + if( !u || !u->ic ) return; if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) { @@ -1104,7 +1104,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) } else { - bim_buddy_msg( u->gc, u->handle, msg, flags ); + bim_buddy_msg( u->ic, u->handle, msg, flags ); } } -- cgit v1.2.3 From aef4828a1dc51de10a43bb7dd5d023de9971295b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 5 Apr 2007 22:20:31 -0700 Subject: More cleanups, mainly in the callbacks. Replaced things like do_error_dialog() and (set|hide)_login_progress(_error)?() with things that hopefully make more sense. Although it's still not really great... --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index b1cae1d9..a78a0153 100644 --- a/irc.c +++ b/irc.c @@ -231,7 +231,7 @@ void irc_free(irc_t * irc) for (account = irc->accounts; account; account = account->next) { if (account->ic) { account->ic->wants_to_die = TRUE; - signoff(account->ic); + imc_logout(account->ic); } else if (account->reconnect) { cancel_auto_reconnect(account); } -- cgit v1.2.3 From c2fb38096ea4e75a680e57e103d4a4986aa84c75 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 15 Apr 2007 15:39:35 -0700 Subject: Cleaned up struct im_connection. No more username/password stuff since it's in acc too. wants_to_die is now an argument to imc_logout(). --- irc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index a78a0153..08ffa753 100644 --- a/irc.c +++ b/irc.c @@ -230,8 +230,7 @@ void irc_free(irc_t * irc) for (account = irc->accounts; account; account = account->next) { if (account->ic) { - account->ic->wants_to_die = TRUE; - imc_logout(account->ic); + imc_logout(account->ic, TRUE); } else if (account->reconnect) { cancel_auto_reconnect(account); } @@ -915,7 +914,7 @@ void irc_kill( irc_t *irc, user_t *u ) if( u->ic->acc->server ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, u->ic->acc->server ); - else if( ( s = strchr( u->ic->username, '@' ) ) ) + else if( ( s = strchr( u->ic->acc->user, '@' ) ) ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, s + 1 ); else -- cgit v1.2.3 From 84b045d409f1e8da6d8bf379c6fef7236dcd9bcd Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 15 Apr 2007 18:03:08 -0700 Subject: s/imc/imcb/ for callback functions. Moved things aroundin nogaim.h a little bit, grouping things by category instead of original Gaim 0.58 filename. --- irc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 08ffa753..7181e660 100644 --- a/irc.c +++ b/irc.c @@ -1036,7 +1036,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) } else if( c && c->ic && c->ic->acc && c->ic->acc->prpl ) { - return( bim_chat_msg( c, s, 0 ) ); + return( imc_chat_msg( c, s, 0 ) ); } return( 0 ); @@ -1051,7 +1051,7 @@ static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_cond return FALSE; u->sendbuf[u->sendbuf_len-2] = 0; /* Cut off the last newline */ - bim_buddy_msg( u->ic, u->handle, u->sendbuf, u->sendbuf_flags ); + imc_buddy_msg( u->ic, u->handle, u->sendbuf, u->sendbuf_flags ); g_free( u->sendbuf ); u->sendbuf = NULL; @@ -1103,7 +1103,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) } else { - bim_buddy_msg( u->ic, u->handle, msg, flags ); + imc_buddy_msg( u->ic, u->handle, msg, flags ); } } -- cgit v1.2.3 From df1fb67d1dbf52d138f63e0d917dda2412d4fc0b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 20 Apr 2007 22:18:40 -0700 Subject: Consistency; Using OPT_T(YP|HINK)ING for outgoing typing notfication crap too. --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 7181e660..e953bfad 100644 --- a/irc.c +++ b/irc.c @@ -1001,7 +1001,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) if( current_typing_notice - u->last_typing_notice >= 5 ) { - u->ic->acc->prpl->send_typing( u->ic, u->handle, s[8] == '1' ); + u->ic->acc->prpl->send_typing( u->ic, u->handle, ( s[8] - '0' ) << 8 ); u->last_typing_notice = current_typing_notice; } } -- cgit v1.2.3 From 0e7ab64dfb66192a875c37322ca6f8a364ec5bc8 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 22 Apr 2007 19:58:44 -0700 Subject: Got rid of one HORRIBLE stupidity called chat_by_channel(), which still used the GLOBAL IM connections list, allowing user A to interfere with user B's groupchats if running in daemon mode. I can't believe this was still there... --- irc.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index e953bfad..eec0ce11 100644 --- a/irc.c +++ b/irc.c @@ -657,7 +657,7 @@ void irc_names( irc_t *irc, char *channel ) strcat( namelist, " " ); } } - else if( ( c = chat_by_channel( channel ) ) ) + else if( ( c = irc_chat_by_channel( irc, channel ) ) ) { GList *l; @@ -810,7 +810,7 @@ void irc_topic( irc_t *irc, char *channel ) } else { - struct groupchat *c = chat_by_channel( channel ); + struct groupchat *c = irc_chat_by_channel( irc, channel ); if( c ) irc_reply( irc, 332, "%s :BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", channel, c->title ); @@ -948,7 +948,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags ) if( *nick == '#' || *nick == '&' ) { - if( !( c = chat_by_channel( nick ) ) ) + if( !( c = irc_chat_by_channel( irc, nick ) ) ) { irc_reply( irc, 403, "%s :Channel does not exist", nick ); return( 0 ); @@ -1214,3 +1214,19 @@ static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond ) return TRUE; } + +struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ) +{ + struct groupchat *c; + account_t *a; + + /* This finds the connection which has a conversation which belongs to this channel */ + for( a = irc->accounts; a; a = a->next ) + { + for( c = a->ic->groupchats; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next ); + if( c ) + return c; + } + + return NULL; +} -- cgit v1.2.3 From bdda9e9ae418e19bd8fa57a019267f567d537018 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 14 Jun 2007 00:32:56 +0100 Subject: Fixed irc_chat_by_channel() to not break if using multiple IM accounts where some of them are down. --- irc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index eec0ce11..ee7288bf 100644 --- a/irc.c +++ b/irc.c @@ -1223,9 +1223,17 @@ struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ) /* This finds the connection which has a conversation which belongs to this channel */ for( a = irc->accounts; a; a = a->next ) { - for( c = a->ic->groupchats; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next ); - if( c ) - return c; + if( a->ic == NULL ) + continue; + + c = a->ic->groupchats; + while( c ) + { + if( c->channel && g_strcasecmp( c->channel, channel ) == 0 ) + return c; + + c = c->next; + } } return NULL; -- cgit v1.2.3 From 8d32b9e8328605bb52c87b53f1f27028e68336e5 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 1 Sep 2007 22:57:22 +0100 Subject: Made UTF-8 the new default charset. This is the default on pretty much every recent machin. --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index e953bfad..254bdbdc 100644 --- a/irc.c +++ b/irc.c @@ -131,7 +131,7 @@ irc_t *irc_new( int fd ) set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc ); set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); - set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc ); + set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); set_add( &irc->set, "debug", "false", set_eval_bool, irc ); set_add( &irc->set, "default_target", "root", NULL, irc ); set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); -- cgit v1.2.3 From 118638279f7a39422d9e07365b380fa773c5243e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 10 Oct 2007 23:15:59 +0100 Subject: Made the netsplit-like quit messages optional. --- irc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 254bdbdc..e1928497 100644 --- a/irc.c +++ b/irc.c @@ -142,6 +142,7 @@ irc_t *irc_new( int fd ) set_add( &irc->set, "private", "true", set_eval_bool, irc ); set_add( &irc->set, "query_order", "lifo", NULL, irc ); set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); + set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); set_add( &irc->set, "strip_html", "true", NULL, irc ); set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); @@ -909,7 +910,7 @@ void irc_kill( irc_t *irc, user_t *u ) char *nick, *s; char reason[128]; - if( u->ic && u->ic->flags & OPT_LOGGING_OUT ) + if( u->ic && u->ic->flags & OPT_LOGGING_OUT && set_getbool( &irc->set, "simulate_netsplit" ) ) { if( u->ic->acc->server ) g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, -- cgit v1.2.3 From e9b755e3726fa41ac2d4ed1c3a6192d1af68edbc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 18 Oct 2007 18:44:25 +0200 Subject: Use standard functions for dealing with both IPv6 and IPv4. --- irc.c | 66 ++++++++++++++++++------------------------------------------------ 1 file changed, 18 insertions(+), 48 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index e1928497..0f8f1b82 100644 --- a/irc.c +++ b/irc.c @@ -44,14 +44,8 @@ static char *passchange( set_t *set, char *value ) irc_t *irc_new( int fd ) { irc_t *irc; - struct hostent *peer; - unsigned int i; - char buf[128]; -#ifdef IPV6 - struct sockaddr_in6 sock6[1]; - unsigned int i6; -#endif - struct sockaddr_in sock[1]; + struct sockaddr_storage sock; + socklen_t socklen = sizeof(sock); irc = g_new0( irc_t, 1 ); @@ -70,54 +64,30 @@ irc_t *irc_new( int fd ) irc->mynick = g_strdup( ROOT_NICK ); irc->channel = g_strdup( ROOT_CHAN ); - i = sizeof( *sock ); -#ifdef IPV6 - i6 = sizeof( *sock6 ); -#endif - if( global.conf->hostname ) irc->myhost = g_strdup( global.conf->hostname ); -#ifdef IPV6 - else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) - { - if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) - irc->myhost = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) - irc->myhost = g_strdup( ipv6_unwrap( buf ) ); - } -#endif - else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) + else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0) { - if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) - irc->myhost = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) - irc->myhost = g_strdup( buf ); + irc->myhost = g_new0(char, NI_MAXHOST); + + if (getnameinfo((struct sockaddr *)&sock, socklen, irc->myhost, + NI_MAXHOST, NULL, -1, 0)) { + /* Rare, but possible. */ + strncpy(irc->myhost, "localhost.", NI_MAXHOST); + } } - i = sizeof( *sock ); -#ifdef IPV6 - i6 = sizeof( *sock6 ); - if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) + if( getpeername( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0) { - if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) - irc->host = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) - irc->host = g_strdup( ipv6_unwrap( buf ) ); - } - else -#endif - if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) - { - if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) - irc->host = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) - irc->host = g_strdup( buf ); + irc->host = g_new0(char, NI_MAXHOST); + + if (getnameinfo((struct sockaddr *)&sock, socklen, irc->host, + NI_MAXHOST, NULL, -1, 0)) { + /* Rare, but possible. */ + strncpy(irc->myhost, "localhost.", NI_MAXHOST); + } } - /* Rare, but possible. */ - if( !irc->host ) irc->host = g_strdup( "localhost." ); - if( !irc->myhost ) irc->myhost = g_strdup( "localhost." ); - if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); -- cgit v1.2.3 From 7435ccf486eee2f60d6a8b2ab0029b8f4ce17ab7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 18 Oct 2007 21:03:02 +0200 Subject: Fix indentation. --- irc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 0f8f1b82..1a1f511e 100644 --- a/irc.c +++ b/irc.c @@ -45,7 +45,7 @@ irc_t *irc_new( int fd ) { irc_t *irc; struct sockaddr_storage sock; - socklen_t socklen = sizeof(sock); + socklen_t socklen = sizeof( sock ); irc = g_new0( irc_t, 1 ); @@ -66,25 +66,25 @@ irc_t *irc_new( int fd ) if( global.conf->hostname ) irc->myhost = g_strdup( global.conf->hostname ); - else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0) + else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 ) { - irc->myhost = g_new0(char, NI_MAXHOST); + irc->myhost = g_new0( char, NI_MAXHOST ); - if (getnameinfo((struct sockaddr *)&sock, socklen, irc->myhost, - NI_MAXHOST, NULL, -1, 0)) { + if (getnameinfo( (struct sockaddr *) &sock, socklen, irc->myhost, + NI_MAXHOST, NULL, -1, 0) ) { /* Rare, but possible. */ - strncpy(irc->myhost, "localhost.", NI_MAXHOST); + strncpy( irc->myhost, "localhost.", NI_MAXHOST ); } } - if( getpeername( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0) + if( getpeername( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 ) { - irc->host = g_new0(char, NI_MAXHOST); + irc->host = g_new0( char, NI_MAXHOST ); - if (getnameinfo((struct sockaddr *)&sock, socklen, irc->host, - NI_MAXHOST, NULL, -1, 0)) { + if ( getnameinfo( (struct sockaddr *)&sock, socklen, irc->host, + NI_MAXHOST, NULL, -1, 0 ) ) { /* Rare, but possible. */ - strncpy(irc->myhost, "localhost.", NI_MAXHOST); + strncpy( irc->myhost, "localhost.", NI_MAXHOST ); } } -- cgit v1.2.3 From 5e2615a2d8a5ae64161727f8a32f6f0949f3fee4 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 30 Oct 2007 23:44:39 +0000 Subject: s/FAQ's/FAQs/ --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index e1928497..1a936d47 100644 --- a/irc.c +++ b/irc.c @@ -743,7 +743,7 @@ void irc_login( irc_t *irc ) u->online = 1; irc_spawn( irc, u ); - irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQ's are answered there." ); + irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there." ); if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); -- cgit v1.2.3 From 50e1776cb0c76b3328d458dd8a1bfb379b6b0e43 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 19 Nov 2007 22:23:58 +0000 Subject: Merging /TOPIC code from Miklos Vajna. Untested, because I still have to implement the Jabber hooks. --- irc.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 72bc5d92..ebb2876b 100644 --- a/irc.c +++ b/irc.c @@ -787,19 +787,14 @@ void irc_motd( irc_t *irc ) void irc_topic( irc_t *irc, char *channel ) { - if( g_strcasecmp( channel, irc->channel ) == 0 ) - { + struct groupchat *c = irc_chat_by_channel( irc, channel ); + + if( c && c->topic ) + irc_reply( irc, 332, "%s :%s", channel, c->topic ); + else if( g_strcasecmp( channel, irc->channel ) == 0 ) irc_reply( irc, 332, "%s :%s", channel, CONTROL_TOPIC ); - } else - { - struct groupchat *c = irc_chat_by_channel( irc, channel ); - - if( c ) - irc_reply( irc, 332, "%s :BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", channel, c->title ); - else - irc_reply( irc, 331, "%s :No topic for this channel", channel ); - } + irc_reply( irc, 331, "%s :No topic for this channel", channel ); } void irc_umode_set( irc_t *irc, char *s, int allow_priv ) -- cgit v1.2.3 From 3e1e11afc869238d5cfca899d4814fea8a877687 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 19 Nov 2007 23:41:42 +0000 Subject: Fixed NULL pointer dereference (in printf) when connected to a non-socket (which I do quite often when testing stuff). --- irc.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index ebb2876b..5531addb 100644 --- a/irc.c +++ b/irc.c @@ -77,11 +77,6 @@ irc_t *irc_new( int fd ) { irc->myhost = g_strdup( ipv6_unwrap( buf ) ); } - else - { - /* Rare, but possible. */ - strncpy( irc->myhost, "localhost.localdomain", NI_MAXHOST ); - } } if( getpeername( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 ) @@ -93,13 +88,13 @@ irc_t *irc_new( int fd ) { irc->host = g_strdup( ipv6_unwrap( buf ) ); } - else - { - /* Rare, but possible. */ - strncpy( irc->host, "localhost.localdomain", NI_MAXHOST ); - } } + if( irc->host == NULL ) + irc->host = g_strdup( "localhost.localdomain" ); + if( irc->myhost == NULL ) + irc->myhost = g_strdup( "localhost.localdomain" ); + if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); -- cgit v1.2.3 From 94d52d64c1ad3d55f210e1fc8e6345d54c4e46d5 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 2 Dec 2007 11:00:15 +0000 Subject: Added charset checks on incoming msgs (from the IRC side) to prevent possible crashes/other odd behaviour in IM modules (or a GLib function that crashes on non-UTF-8 strings). --- irc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 5531addb..01d4c47e 100644 --- a/irc.c +++ b/irc.c @@ -319,11 +319,22 @@ void irc_process( irc_t *irc ) break; } - if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) + if( ( cs = set_getstr( &irc->set, "charset" ) ) ) { conv[IRC_MAX_LINE] = 0; - if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) != -1 ) - lines[i] = conv; + if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) + { + if( irc->status & USTATUS_LOGGED_IN ) + irc_usermsg( irc, "ERROR: Charset mismatch detected. The charset " + "setting is currently set to %s, so please make " + "sure your IRC client will send and accept text in " + "that charset, or tell BitlBee which charset to " + "expect by changing the charset setting. See " + "`help set charset' for more information. Your " + "message was ignored.", cs ); + *conv = 0; + } + lines[i] = conv; } if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) -- cgit v1.2.3 From 434627083613f016d432462fce73f728dd77172e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 6 Jan 2008 12:37:55 +0000 Subject: More consistency in error/warning errors. Until now "WARNING:" was usually in upper case while "Error:" wasn't .... that doesn't really make sense. --- irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 01d4c47e..2b86aebb 100644 --- a/irc.c +++ b/irc.c @@ -325,7 +325,7 @@ void irc_process( irc_t *irc ) if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) { if( irc->status & USTATUS_LOGGED_IN ) - irc_usermsg( irc, "ERROR: Charset mismatch detected. The charset " + irc_usermsg( irc, "Error: Charset mismatch detected. The charset " "setting is currently set to %s, so please make " "sure your IRC client will send and accept text in " "that charset, or tell BitlBee which charset to " -- cgit v1.2.3 From fc0cf92a81086903914056b32663479909a6fbff Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 13 Jan 2008 00:15:12 +0000 Subject: Different handling of charset mismatches before login time. Ignoring a USER command because of encoding issues isn't too great, so let's simply replace them. The information isn't really used anywhere anyway. --- irc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 2b86aebb..972e030e 100644 --- a/irc.c +++ b/irc.c @@ -324,7 +324,10 @@ void irc_process( irc_t *irc ) conv[IRC_MAX_LINE] = 0; if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) { + /* GLib can do strange things if things are not in the expected charset, + so let's be a little bit paranoid here: */ if( irc->status & USTATUS_LOGGED_IN ) + { irc_usermsg( irc, "Error: Charset mismatch detected. The charset " "setting is currently set to %s, so please make " "sure your IRC client will send and accept text in " @@ -332,7 +335,18 @@ void irc_process( irc_t *irc ) "expect by changing the charset setting. See " "`help set charset' for more information. Your " "message was ignored.", cs ); - *conv = 0; + *conv = 0; + } + else + { + irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, + "Warning: invalid (non-UTF8) characters received at login time." ); + + strncpy( conv, lines[i], IRC_MAX_LINE ); + for( temp = conv; *temp; temp ++ ) + if( *temp & 0x80 ) + *temp = '?'; + } } lines[i] = conv; } -- cgit v1.2.3 From 0fbda19314c806e3e677847f3c977eb5a1bc2b61 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 2 Feb 2008 21:48:09 +0000 Subject: Added help_free() and cleaned up some very stale help-related stuff I wasn't even aware of. This closes bug #352. --- irc.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 972e030e..2510e3d9 100644 --- a/irc.c +++ b/irc.c @@ -188,7 +188,6 @@ void irc_free(irc_t * irc) { account_t *account; user_t *user, *usertmp; - help_t *helpnode, *helpnodetmp; log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); @@ -265,16 +264,6 @@ void irc_free(irc_t * irc) g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); g_hash_table_destroy(irc->watches); - if (irc->help != NULL) { - helpnode = irc->help; - while (helpnode != NULL) { - g_free(helpnode->string); - - helpnodetmp = helpnode; - helpnode = helpnode->next; - g_free(helpnodetmp); - } - } g_free(irc); if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) -- cgit v1.2.3 From c84e31ae1e972a327b103ada52cae6a2e2335767 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 7 Feb 2008 21:25:18 +0000 Subject: Fixed getnameinfo() calls, this fixes Solaris stability issues. Thanks to Logan O'Sullivan Bruns for the report. --- irc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 2510e3d9..3a09f684 100644 --- a/irc.c +++ b/irc.c @@ -73,7 +73,7 @@ irc_t *irc_new( int fd ) char buf[NI_MAXHOST+1]; if( getnameinfo( (struct sockaddr *) &sock, socklen, buf, - NI_MAXHOST, NULL, -1, 0 ) == 0 ) + NI_MAXHOST, NULL, 0, 0 ) == 0 ) { irc->myhost = g_strdup( ipv6_unwrap( buf ) ); } @@ -84,7 +84,7 @@ irc_t *irc_new( int fd ) char buf[NI_MAXHOST+1]; if( getnameinfo( (struct sockaddr *)&sock, socklen, buf, - NI_MAXHOST, NULL, -1, 0 ) == 0 ) + NI_MAXHOST, NULL, 0, 0 ) == 0 ) { irc->host = g_strdup( ipv6_unwrap( buf ) ); } -- cgit v1.2.3 From a83442a7c4dbf99937e9e5397e5665c671694161 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 21 Mar 2008 00:39:16 +0000 Subject: Fixed handling of "set charset none". Fixes bug #373. --- irc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 3a09f684..3589256e 100644 --- a/irc.c +++ b/irc.c @@ -308,7 +308,7 @@ void irc_process( irc_t *irc ) break; } - if( ( cs = set_getstr( &irc->set, "charset" ) ) ) + if( ( cs = set_getstr( &irc->set, "charset" ) ) && g_strcasecmp( cs, "none" ) != 0 ) { conv[IRC_MAX_LINE] = 0; if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) @@ -329,7 +329,7 @@ void irc_process( irc_t *irc ) else { irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, - "Warning: invalid (non-UTF8) characters received at login time." ); + "Warning: invalid characters received at login time." ); strncpy( conv, lines[i], IRC_MAX_LINE ); for( temp = conv; *temp; temp ++ ) @@ -553,7 +553,8 @@ void irc_vawrite( irc_t *irc, char *format, va_list params ) g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); strip_newlines( line ); - if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) + if( ( cs = set_getstr( &irc->set, "charset" ) ) && + g_strcasecmp( cs, "none" ) != 0 && g_strcasecmp( cs, "utf-8" ) != 0 ) { char conv[IRC_MAX_LINE+1]; -- cgit v1.2.3 From a199d33ed818820ffba328f718799bbd77392f6a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 29 Mar 2008 22:19:17 +0000 Subject: Closing bug #209: The PASS command can now be used to identify yourself to BitlBee. The advantage: No more messing with NickServ hooks. Just set a server password. --- irc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 3589256e..fa0c03fe 100644 --- a/irc.c +++ b/irc.c @@ -735,12 +735,27 @@ void irc_login( irc_t *irc ) u->online = 1; irc_spawn( irc, u ); - irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there." ); + irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" + "If you've never used BitlBee before, please do read the help " + "information using the \x02help\x02 command. Lots of FAQs are " + "answered there.\n" + "If you already have an account on this server, just use the " + "\x02identify\x02 command to identify yourself." ); if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); irc->status |= USTATUS_LOGGED_IN; + + /* This is for bug #209 (use PASS to identify to NickServ). */ + if( irc->password != NULL ) + { + char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; + + irc_setpass( irc, NULL ); + root_command( irc, send_cmd ); + g_free( send_cmd[1] ); + } } void irc_motd( irc_t *irc ) -- cgit v1.2.3 From 18ff38fad0d6d47853fb43ec5a99b29ba031a8ca Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 29 Mar 2008 23:15:04 +0000 Subject: Be more liberal with accepted line endings. ERC on Windows likes to use "\r\r\n", for example, and until now BitlBee only chopped off the \r\n, leaving the first \r as part of the command, which means it couldn't log in to BitlBee at all. (Bad character in nickname.) --- irc.c | 54 ++++++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index fa0c03fe..99f0de9a 100644 --- a/irc.c +++ b/irc.c @@ -296,9 +296,8 @@ void irc_process( irc_t *irc ) { char conv[IRC_MAX_LINE+1]; - /* [WvG] Because irc_tokenize splits at every newline, the lines[] list - should end with an empty string. This is why this actually works. - Took me a while to figure out, Maurits. :-P */ + /* [WvG] If the last line isn't empty, it's an incomplete line and we + should wait for the rest to come in before processing it. */ if( lines[i+1] == NULL ) { temp = g_strdup( lines[i] ); @@ -368,42 +367,41 @@ void irc_process( irc_t *irc ) contains an incomplete line at the end, ends with an empty string. */ char **irc_tokenize( char *buffer ) { - int i, j; + int i, j, n = 3; char **lines; - /* Count the number of elements we're gonna need. */ - for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) - { - if( buffer[i] == '\n' ) - if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) - j ++; - } - - /* Allocate j+1 elements. */ - lines = g_new( char *, j + 1 ); - - /* NULL terminate our list. */ - lines[j] = NULL; + /* Allocate n+1 elements. */ + lines = g_new( char *, n + 1 ); lines[0] = buffer; - /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. - * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. - */ - for( i = 0, j = 0; buffer[i] != '\0'; i ++) + /* Split the buffer in several strings, and accept any kind of line endings, + * knowing that ERC on Windows may send something interesting like \r\r\n, + * and surely there must be clients that think just \n is enough... */ + for( i = 0, j = 0; buffer[i] != '\0'; i ++ ) { - if( buffer[i] == '\n' ) + if( buffer[i] == '\r' || buffer[i] == '\n' ) { - buffer[i] = '\0'; + while( buffer[i] == '\r' || buffer[i] == '\n' ) + buffer[i++] = '\0'; - if( i > 0 && buffer[i-1] == '\r' ) - buffer[i-1] = '\0'; - if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) - lines[++j] = buffer + i + 1; + lines[++j] = buffer + i; + + if( j >= n ) + { + n *= 2; + lines = g_renew( char *, lines, n + 1 ); + } + + if( buffer[i] == '\0' ) + break; } } - return( lines ); + /* NULL terminate our list. */ + lines[++j] = NULL; + + return lines; } /* Split an IRC-style line into little parts/arguments. */ -- cgit v1.2.3 From f9756bd2e2711d58e06ad2a33ad3292ff10fc6da Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 30 Mar 2008 22:26:16 +0100 Subject: Changed charset handling: irc_t keeps two iconv structures, which are just used for every line sent and received, so now there's no need to use g_iconv_open() every time a message comes in/out. Also, fixed a small memory leak that was there for a long time but somehow never caught my attention. --- irc.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 23 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 99f0de9a..2faa2bc1 100644 --- a/irc.c +++ b/irc.c @@ -41,6 +41,35 @@ static char *passchange( set_t *set, char *value ) return NULL; } +static char *set_eval_charset( set_t *set, char *value ) +{ + irc_t *irc = set->data; + GIConv ic, oc; + + if( g_strcasecmp( value, "none" ) == 0 ) + value = g_strdup( "utf-8" ); + + if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) + { + return NULL; + } + if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) + { + g_iconv_close( ic ); + return NULL; + } + + if( irc->iconv != (GIConv) -1 ) + g_iconv_close( irc->iconv ); + if( irc->oconv != (GIConv) -1 ) + g_iconv_close( irc->oconv ); + + irc->iconv = ic; + irc->oconv = oc; + + return value; +} + irc_t *irc_new( int fd ) { irc_t *irc; @@ -64,6 +93,9 @@ irc_t *irc_new( int fd ) irc->mynick = g_strdup( ROOT_NICK ); irc->channel = g_strdup( ROOT_CHAN ); + irc->iconv = (GIConv) -1; + irc->oconv = (GIConv) -1; + if( global.conf->hostname ) { irc->myhost = g_strdup( global.conf->hostname ); @@ -126,6 +158,9 @@ irc_t *irc_new( int fd ) conf_loaddefaults( irc ); + /* Evaluator sets the iconv/oconv structures. */ + set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); + return( irc ); } @@ -264,6 +299,13 @@ void irc_free(irc_t * irc) g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); g_hash_table_destroy(irc->watches); + if( irc->iconv != (GIConv) -1 ) + g_iconv_close( irc->iconv ); + if( irc->oconv != (GIConv) -1 ) + g_iconv_close( irc->oconv ); + + g_free( irc->last_target ); + g_free(irc); if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) @@ -285,7 +327,7 @@ void irc_setpass (irc_t *irc, const char *pass) void irc_process( irc_t *irc ) { - char **lines, *temp, **cmd, *cs; + char **lines, *temp, **cmd; int i; if( irc->readbuffer != NULL ) @@ -294,7 +336,7 @@ void irc_process( irc_t *irc ) for( i = 0; *lines[i] != '\0'; i ++ ) { - char conv[IRC_MAX_LINE+1]; + char *conv = NULL; /* [WvG] If the last line isn't empty, it's an incomplete line and we should wait for the rest to come in before processing it. */ @@ -307,10 +349,14 @@ void irc_process( irc_t *irc ) break; } - if( ( cs = set_getstr( &irc->set, "charset" ) ) && g_strcasecmp( cs, "none" ) != 0 ) + if( irc->iconv != (GIConv) -1 ) { - conv[IRC_MAX_LINE] = 0; - if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) + gsize bytes_read, bytes_written; + + conv = g_convert_with_iconv( lines[i], -1, irc->iconv, + &bytes_read, &bytes_written, NULL ); + + if( conv == NULL || bytes_read != strlen( lines[i] ) ) { /* GLib can do strange things if things are not in the expected charset, so let's be a little bit paranoid here: */ @@ -322,15 +368,18 @@ void irc_process( irc_t *irc ) "that charset, or tell BitlBee which charset to " "expect by changing the charset setting. See " "`help set charset' for more information. Your " - "message was ignored.", cs ); - *conv = 0; + "message was ignored.", + set_getstr( &irc->set, "charset" ) ); + + g_free( conv ); + conv = NULL; } else { irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "Warning: invalid characters received at login time." ); - strncpy( conv, lines[i], IRC_MAX_LINE ); + conv = g_strdup( lines[i] ); for( temp = conv; *temp; temp ++ ) if( *temp & 0x80 ) *temp = '?'; @@ -339,11 +388,15 @@ void irc_process( irc_t *irc ) lines[i] = conv; } - if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) - continue; - irc_exec( irc, cmd ); + if( lines[i] ) + { + if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) + continue; + irc_exec( irc, cmd ); + g_free( cmd ); + } - g_free( cmd ); + g_free( conv ); /* Shouldn't really happen, but just in case... */ if( !g_slist_find( irc_connection_list, irc ) ) @@ -535,32 +588,35 @@ void irc_write( irc_t *irc, char *format, ... ) va_end( params ); return; - } void irc_vawrite( irc_t *irc, char *format, va_list params ) { int size; - char line[IRC_MAX_LINE+1], *cs; + char line[IRC_MAX_LINE+1]; /* Don't try to write anything new anymore when shutting down. */ if( irc->status & USTATUS_SHUTDOWN ) return; - line[IRC_MAX_LINE] = 0; + memset( line, 0, sizeof( line ) ); g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); - strip_newlines( line ); - if( ( cs = set_getstr( &irc->set, "charset" ) ) && - g_strcasecmp( cs, "none" ) != 0 && g_strcasecmp( cs, "utf-8" ) != 0 ) + + if( irc->oconv != (GIConv) -1 ) { - char conv[IRC_MAX_LINE+1]; + gsize bytes_read, bytes_written; + char *conv; + + conv = g_convert_with_iconv( line, -1, irc->oconv, + &bytes_read, &bytes_written, NULL ); + + if( bytes_read == strlen( line ) ) + strncpy( line, conv, IRC_MAX_LINE - 2 ); - conv[IRC_MAX_LINE] = 0; - if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 ) - strcpy( line, conv ); + g_free( conv ); } - strcat( line, "\r\n" ); + g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 ); if( irc->sendbuffer != NULL ) { -- cgit v1.2.3 From fa75134008bd9206ca02380927c27581feb65c3e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 2 Apr 2008 00:07:21 +0100 Subject: Reordered irc_free() a little bit, hoping that this will fix a crash-on-quit bug I can't figure out. The previous order wasn't optimal. --- irc.c | 111 +++++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 56 insertions(+), 55 deletions(-) (limited to 'irc.c') diff --git a/irc.c b/irc.c index 2faa2bc1..585cf232 100644 --- a/irc.c +++ b/irc.c @@ -219,9 +219,8 @@ static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ) } /* Because we have no garbage collection, this is quite annoying */ -void irc_free(irc_t * irc) +void irc_free( irc_t * irc ) { - account_t *account; user_t *user, *usertmp; log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); @@ -230,83 +229,85 @@ void irc_free(irc_t * irc) if( storage_save( irc, TRUE ) != STORAGE_OK ) irc_usermsg( irc, "Error while saving settings!" ); - closesocket( irc->fd ); - - if( irc->ping_source_id > 0 ) - b_event_remove( irc->ping_source_id ); - b_event_remove( irc->r_watch_source_id ); - if( irc->w_watch_source_id > 0 ) - b_event_remove( irc->w_watch_source_id ); - irc_connection_list = g_slist_remove( irc_connection_list, irc ); - for (account = irc->accounts; account; account = account->next) { - if (account->ic) { - imc_logout(account->ic, TRUE); - } else if (account->reconnect) { - cancel_auto_reconnect(account); - } - } - - g_free(irc->sendbuffer); - g_free(irc->readbuffer); - - g_free(irc->nick); - g_free(irc->user); - g_free(irc->host); - g_free(irc->realname); - g_free(irc->password); - - g_free(irc->myhost); - g_free(irc->mynick); - - g_free(irc->channel); - - while (irc->queries != NULL) - query_del(irc, irc->queries); - - while (irc->accounts) - if (irc->accounts->ic == NULL) - account_del(irc, irc->accounts); + while( irc->accounts ) + { + if( irc->accounts->ic ) + imc_logout( irc->accounts->ic, FALSE ); + else if( irc->accounts->reconnect ) + cancel_auto_reconnect( irc->accounts ); + + if( irc->accounts->ic == NULL ) + account_del( irc, irc->accounts ); else /* Nasty hack, but account_del() doesn't work in this case and we don't want infinite loops, do we? ;-) */ irc->accounts = irc->accounts->next; + } + + while( irc->queries != NULL ) + query_del( irc, irc->queries ); - while (irc->set) - set_del(&irc->set, irc->set->key); + while( irc->set ) + set_del( &irc->set, irc->set->key ); - if (irc->users != NULL) { + if (irc->users != NULL) + { user = irc->users; - while (user != NULL) { - g_free(user->nick); - g_free(user->away); - g_free(user->handle); - if(user->user!=user->nick) g_free(user->user); - if(user->host!=user->nick) g_free(user->host); - if(user->realname!=user->nick) g_free(user->realname); - b_event_remove(user->sendbuf_timer); + while( user != NULL ) + { + g_free( user->nick ); + g_free( user->away ); + g_free( user->handle ); + if( user->user != user->nick ) g_free( user->user ); + if( user->host != user->nick ) g_free( user->host ); + if( user->realname != user->nick ) g_free( user->realname ); + b_event_remove( user->sendbuf_timer ); usertmp = user; user = user->next; - g_free(usertmp); + g_free( usertmp ); } } - g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL); - g_hash_table_destroy(irc->userhash); + if( irc->ping_source_id > 0 ) + b_event_remove( irc->ping_source_id ); + b_event_remove( irc->r_watch_source_id ); + if( irc->w_watch_source_id > 0 ) + b_event_remove( irc->w_watch_source_id ); + + closesocket( irc->fd ); + irc->fd = -1; + + g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); + g_hash_table_destroy( irc->userhash ); - g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); - g_hash_table_destroy(irc->watches); + g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); + g_hash_table_destroy( irc->watches ); if( irc->iconv != (GIConv) -1 ) g_iconv_close( irc->iconv ); if( irc->oconv != (GIConv) -1 ) g_iconv_close( irc->oconv ); + g_free( irc->sendbuffer ); + g_free( irc->readbuffer ); + + g_free( irc->nick ); + g_free( irc->user ); + g_free( irc->host ); + g_free( irc->realname ); + g_free( irc->password ); + + g_free( irc->myhost ); + g_free( irc->mynick ); + + g_free( irc->channel ); + g_free( irc->last_target ); - g_free(irc); + g_free( irc ); if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) b_main_quit(); -- cgit v1.2.3