diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-01-15 16:42:20 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-01-15 16:42:20 +0100 | 
| commit | 74c119dd1b066329eba59d057935ba7ec7249555 (patch) | |
| tree | c46aa45053fab63b071559bd5780473056a953e1 | |
| parent | 13caf0aa5d1e5575b74221e0cd9e4ff9f4cd79a8 (diff) | |
Better DIE implementation, added SO_REUSEADDR to listening socket.
| -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, ... ); | 
