aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.c4
-rw-r--r--conf.c12
-rw-r--r--ipc.c86
-rw-r--r--ipc.h2
-rw-r--r--irc.c31
-rw-r--r--irc.h1
6 files changed, 93 insertions, 43 deletions
diff --git a/bitlbee.c b/bitlbee.c
index f6605552..dc6b8261 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -55,6 +55,10 @@ int bitlbee_daemon_init()
return( -1 );
}
+ /* TIME_WAIT (?) sucks.. */
+ i = 1;
+ setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
+
#ifdef IPV6
listen_addr.sin6_family = AF_INETx;
listen_addr.sin6_port = htons( global.conf->port );
diff --git a/conf.c b/conf.c
index 6ec20015..dd165869 100644
--- a/conf.c
+++ b/conf.c
@@ -91,15 +91,15 @@ conf_t *conf_load( int argc, char *argv[] )
conf->port = i;
}
else if( opt == 'n' )
- conf->nofork=1;
+ conf->nofork = 1;
else if( opt == 'v' )
- conf->verbose=1;
+ conf->verbose = 1;
else if( opt == 'I' )
- conf->runmode=RUNMODE_INETD;
+ conf->runmode = RUNMODE_INETD;
else if( opt == 'D' )
- conf->runmode=RUNMODE_DAEMON;
+ conf->runmode = RUNMODE_DAEMON;
else if( opt == 'F' )
- conf->runmode=RUNMODE_FORKDAEMON;
+ conf->runmode = RUNMODE_FORKDAEMON;
else if( opt == 'c' )
{
if( strcmp( CONF_FILE, optarg ) != 0 )
@@ -107,6 +107,8 @@ conf_t *conf_load( int argc, char *argv[] )
g_free( CONF_FILE );
CONF_FILE = g_strdup( optarg );
g_free( conf );
+ /* Re-evaluate arguments. */
+ optind = 1;
return( conf_load( argc, argv ) );
}
}
diff --git a/ipc.c b/ipc.c
index 03c44827..f7435776 100644
--- a/ipc.c
+++ b/ipc.c
@@ -30,36 +30,39 @@
GSList *child_list = NULL;
+
static int ipc_master_cmd_die( irc_t *data, char **cmd )
{
+ if( global.conf->runmode == RUNMODE_FORKDAEMON )
+ ipc_to_children_str( "DIE\r\n" );
+
bitlbee_shutdown( NULL );
+
+ return 1;
}
static int ipc_master_cmd_wallops( irc_t *data, char **cmd )
{
- GSList *l;
- char msg_buf[513];
- int msg_len;
-
- if( ( msg_len = g_snprintf( msg_buf, sizeof( msg_buf ) - 1, "%s :%s\r\n", cmd[0], cmd[1] ) ) > ( sizeof( msg_buf ) - 1 ) )
- return 0;
-
- for( l = child_list; l; l = l->next )
- {
- struct bitlbee_child *c = l->data;
- write( c->ipc_fd, msg_buf, msg_len );
- }
+ ipc_to_children( cmd );
return 1;
}
static const command_t ipc_master_commands[] = {
{ "die", 0, ipc_master_cmd_die, 0 },
- { "wallops", 1, ipc_master_cmd_wallops, 1 },
- { "lilo", 1, ipc_master_cmd_wallops, 1 },
+ { "wallops", 1, ipc_master_cmd_wallops, 0 },
+ { "lilo", 1, ipc_master_cmd_wallops, 0 },
{ NULL }
};
+
+static int ipc_child_cmd_die( irc_t *data, char **cmd )
+{
+ bitlbee_shutdown( NULL );
+
+ return 1;
+}
+
static int ipc_child_cmd_wallops( irc_t *data, char **cmd )
{
irc_t *irc = data;
@@ -74,17 +77,20 @@ static int ipc_child_cmd_lilo( irc_t *data, char **cmd )
{
irc_t *irc = data;
- irc_write( irc, ":%s NOTICE %s :%s", irc->myhost, irc->nick, cmd[1] );
+ if( strchr( irc->umode, 's' ) )
+ irc_write( irc, ":%s NOTICE %s :%s", irc->myhost, irc->nick, cmd[1] );
return 1;
}
static const command_t ipc_child_commands[] = {
- { "wallops", 1, ipc_child_cmd_wallops, 1 },
- { "lilo", 1, ipc_child_cmd_lilo, 1 },
+ { "die", 0, ipc_child_cmd_die, 0 },
+ { "wallops", 1, ipc_child_cmd_wallops, 0 },
+ { "lilo", 1, ipc_child_cmd_lilo, 0 },
{ NULL }
};
+
static void ipc_command_exec( void *data, char **cmd, const command_t *commands )
{
int i;
@@ -190,29 +196,33 @@ void ipc_to_master( char **cmd )
{
if( global.conf->runmode == RUNMODE_FORKDAEMON )
{
- int i, len;
- char *s;
-
- len = 1;
- for( i = 0; cmd[i]; i ++ )
- len += strlen( cmd[i] ) + 1;
-
- if( strchr( cmd[i-1], ' ' ) != NULL )
- len ++;
+ char *s = irc_build_line( cmd );
+ write( global.listen_socket, s, strlen( s ) );
+ g_free( s );
+ }
+}
+
+void ipc_to_children( char **cmd )
+{
+ if( global.conf->runmode == RUNMODE_FORKDAEMON )
+ {
+ char *msg_buf = irc_build_line( cmd );
+ ipc_to_children_str( msg_buf );
+ g_free( msg_buf );
+ }
+}
+
+void ipc_to_children_str( char *msg_buf )
+{
+ if( global.conf->runmode == RUNMODE_FORKDAEMON )
+ {
+ int msg_len = strlen( msg_buf );
+ GSList *l;
- s = g_new0( char, len + 1 );
- for( i = 0; cmd[i]; i ++ )
+ for( l = child_list; l; l = l->next )
{
- if( cmd[i+1] == NULL && strchr( cmd[i], ' ' ) != NULL )
- strcat( s, ":" );
-
- strcat( s, cmd[i] );
-
- if( cmd[i+1] )
- strcat( s, " " );
+ struct bitlbee_child *c = l->data;
+ write( c->ipc_fd, msg_buf, msg_len );
}
- strcat( s, "\r\n" );
-
- write( global.listen_socket, s, len );
}
}
diff --git a/ipc.h b/ipc.h
index 8c48147c..393cb0aa 100644
--- a/ipc.h
+++ b/ipc.h
@@ -29,6 +29,8 @@
void ipc_master_read( gpointer data, gint source, GaimInputCondition cond );
void ipc_child_read( gpointer data, gint source, GaimInputCondition cond );
void ipc_to_master( char **cmd );
+void ipc_to_children( char **cmd );
+void ipc_to_children_str( char *msg_buf );
struct bitlbee_child
{
diff --git a/irc.c b/irc.c
index a00c4192..a0ba6e53 100644
--- a/irc.c
+++ b/irc.c
@@ -433,6 +433,37 @@ char **irc_parse_line( char *line )
return cmd;
}
+char *irc_build_line( char **cmd )
+{
+ int i, len;
+ char *s;
+
+ if( cmd[0] == NULL )
+ return NULL;
+
+ len = 1;
+ for( i = 0; cmd[i]; i ++ )
+ len += strlen( cmd[i] ) + 1;
+
+ if( strchr( cmd[i-1], ' ' ) != NULL )
+ len ++;
+
+ s = g_new0( char, len + 1 );
+ for( i = 0; cmd[i]; i ++ )
+ {
+ if( cmd[i+1] == NULL && strchr( cmd[i], ' ' ) != NULL )
+ strcat( s, ":" );
+
+ strcat( s, cmd[i] );
+
+ if( cmd[i+1] )
+ strcat( s, " " );
+ }
+ strcat( s, "\r\n" );
+
+ return s;
+}
+
void irc_reply( irc_t *irc, int code, char *format, ... )
{
char text[IRC_MAX_LINE];
diff --git a/irc.h b/irc.h
index 8517bb7e..c8246c16 100644
--- a/irc.h
+++ b/irc.h
@@ -108,6 +108,7 @@ void irc_free( irc_t *irc );
int irc_exec( irc_t *irc, char **cmd );
int irc_process( irc_t *irc );
char **irc_parse_line( char *line );
+char *irc_build_line( char **cmd );
void irc_vawrite( irc_t *irc, char *format, va_list params );
void irc_write( irc_t *irc, char *format, ... );