aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-07-10 16:08:02 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-07-10 16:08:02 +0100
commitf1c2b21af3a51796b747ca4dbc2cdec9611efc5d (patch)
tree067321e4a5c3073e5a9da44a8215a89ebd33bb1d
parent534e4069e0cfa8aee82f82603dc3ca05562a85dd (diff)
Cleanup. Move some code to a more appropriate location, and show the old
connection a quit message instead of just breaking the connection.
-rw-r--r--ipc.c32
-rw-r--r--ipc.h2
-rw-r--r--irc.c79
-rw-r--r--irc.h5
-rw-r--r--root_commands.c3
5 files changed, 91 insertions, 30 deletions
diff --git a/ipc.c b/ipc.c
index b4b31da1..a92d5a0f 100644
--- a/ipc.c
+++ b/ipc.c
@@ -332,27 +332,10 @@ static void ipc_child_cmd_takeover( irc_t *irc, char **cmd )
strcmp( irc->user->nick, cmd[2] ) == 0 &&
strcmp( irc->password, cmd[3] ) == 0 )
{
- GSList *l;
-
- /* TODO: Move this all into irc_switch_fd() or so and
- irc_sync() */
- b_event_remove( irc->r_watch_source_id );
- closesocket( irc->fd );
- irc->fd = ipc_child_recv_fd;
- irc->r_watch_source_id = b_input_add( irc->fd, B_EV_IO_READ, bitlbee_io_current_client_read, irc );
- ipc_child_recv_fd = -1;
-
- irc_write( irc, ":%s!%s@%s MODE %s :+%s", irc->user->nick,
- irc->user->user, irc->user->host, irc->user->nick,
- irc->umode );
-
- for( l = irc->channels; l; l = l->next )
- {
- irc_channel_t *ic = l->data;
- if( ic->flags & IRC_CHANNEL_JOINED )
- irc_send_join( ic, irc->user );
- }
+ irc_switch_fd( irc, ipc_child_recv_fd );
+ irc_sync( irc );
irc_usermsg( irc, "You've successfully taken over your old session" );
+ ipc_child_recv_fd = -1;
ipc_to_master_str( "TAKEOVER DONE\r\n" );
}
@@ -376,7 +359,6 @@ static void ipc_child_cmd_takeover( irc_t *irc, char **cmd )
static void ipc_child_cmd_takeover_yes( void *data )
{
irc_t *irc = data;
- GSList *l;
/* Master->New connection */
ipc_to_master_str( "TAKEOVER AUTH %s :%s\r\n",
@@ -391,13 +373,7 @@ static void ipc_child_cmd_takeover_yes( void *data )
irc->status &= ~USTATUS_IDENTIFIED;
irc_umode_set( irc, "-R", 1 );
- for( l = irc->channels; l; l = l->next )
- irc_channel_del_user( l->data, irc->user, IRC_CDU_KICK,
- "Switching to old session" );
-
- irc_write( irc, ":%s!%s@%s MODE %s :-%s", irc->user->nick,
- irc->user->user, irc->user->host, irc->user->nick,
- irc->umode );
+ irc_desync( irc );
}
static void ipc_child_cmd_takeover_no( void *data )
diff --git a/ipc.h b/ipc.h
index bf5f0454..068996a7 100644
--- a/ipc.h
+++ b/ipc.h
@@ -54,6 +54,8 @@ void ipc_master_free_all();
void ipc_child_disable();
+gboolean ipc_child_identify( irc_t *irc );
+
void ipc_to_master( char **cmd );
void ipc_to_master_str( char *format, ... ) G_GNUC_PRINTF( 1, 2 );
void ipc_to_children( char **cmd );
diff --git a/irc.c b/irc.c
index cb1d0867..f616ef40 100644
--- a/irc.c
+++ b/irc.c
@@ -618,6 +618,85 @@ void irc_vawrite( irc_t *irc, char *format, va_list params )
return;
}
+/* Flush sendbuffer if you can. If it fails, fail silently and let some
+ I/O event handler clean up. */
+void irc_flush( irc_t *irc )
+{
+ ssize_t n;
+ size_t len;
+
+ if( irc->sendbuffer == NULL )
+ return;
+
+ len = strlen( irc->sendbuffer );
+ if( ( n = send( irc->fd, irc->sendbuffer, len, 0 ) ) == len )
+ {
+ g_free( irc->sendbuffer );
+ irc->sendbuffer = NULL;
+
+ b_event_remove( irc->w_watch_source_id );
+ irc->w_watch_source_id = 0;
+ }
+ else if( n > 0 )
+ {
+ char *s = g_strdup( irc->sendbuffer + n );
+ g_free( irc->sendbuffer );
+ irc->sendbuffer = s;
+ }
+ /* Otherwise something went wrong and we don't currently care
+ what the error was. We may or may not succeed later, we
+ were just trying to flush the buffer immediately. */
+}
+
+/* Meant for takeover functionality. Transfer an IRC connection to a different
+ socket. */
+void irc_switch_fd( irc_t *irc, int fd )
+{
+ irc_write( irc, "ERROR :Transferring session to a new connection" );
+ irc_flush( irc ); /* Write it now or forget about it forever. */
+
+ if( irc->sendbuffer )
+ {
+ b_event_remove( irc->w_watch_source_id );
+ g_free( irc->sendbuffer );
+ irc->sendbuffer = irc->w_watch_source_id = 0;
+ }
+
+ b_event_remove( irc->r_watch_source_id );
+ closesocket( irc->fd );
+ irc->fd = fd;
+ irc->r_watch_source_id = b_input_add( irc->fd, B_EV_IO_READ, bitlbee_io_current_client_read, irc );
+}
+
+void irc_sync( irc_t *irc )
+{
+ GSList *l;
+
+ irc_write( irc, ":%s!%s@%s MODE %s :+%s", irc->user->nick,
+ irc->user->user, irc->user->host, irc->user->nick,
+ irc->umode );
+
+ for( l = irc->channels; l; l = l->next )
+ {
+ irc_channel_t *ic = l->data;
+ if( ic->flags & IRC_CHANNEL_JOINED )
+ irc_send_join( ic, irc->user );
+ }
+}
+
+void irc_desync( irc_t *irc )
+{
+ GSList *l;
+
+ for( l = irc->channels; l; l = l->next )
+ irc_channel_del_user( l->data, irc->user, IRC_CDU_KICK,
+ "Switching to old session" );
+
+ irc_write( irc, ":%s!%s@%s MODE %s :-%s", irc->user->nick,
+ irc->user->user, irc->user->host, irc->user->nick,
+ irc->umode );
+}
+
int irc_check_login( irc_t *irc )
{
if( irc->user->user && irc->user->nick )
diff --git a/irc.h b/irc.h
index 3b5e244f..1d5bd113 100644
--- a/irc.h
+++ b/irc.h
@@ -229,6 +229,11 @@ void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
void irc_write_all( int now, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
void irc_vawrite( irc_t *irc, char *format, va_list params );
+void irc_flush( irc_t *irc );
+void irc_switch_fd( irc_t *irc, int fd );
+void irc_sync( irc_t *irc );
+void irc_desync( irc_t *irc );
+
int irc_check_login( irc_t *irc );
void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv );
diff --git a/root_commands.c b/root_commands.c
index cf448e8d..6fa4fd54 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -27,8 +27,7 @@
#include "commands.h"
#include "bitlbee.h"
#include "help.h"
-
-#include <string.h>
+#include "ipc.h"
void root_command_string( irc_t *irc, char *command )
{