diff options
-rw-r--r-- | bitlbee.c | 4 | ||||
-rw-r--r-- | conf.c | 12 | ||||
-rw-r--r-- | ipc.c | 86 | ||||
-rw-r--r-- | ipc.h | 2 | ||||
-rw-r--r-- | irc.c | 31 | ||||
-rw-r--r-- | irc.h | 1 |
6 files changed, 93 insertions, 43 deletions
@@ -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 ); @@ -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 ) ); } } @@ -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 ); } } @@ -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 { @@ -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]; @@ -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, ... ); |