diff options
| author | Jelmer Vernooij <jelmer@samba.org> | 2008-04-02 16:22:57 +0200 | 
|---|---|---|
| committer | Jelmer Vernooij <jelmer@samba.org> | 2008-04-02 16:22:57 +0200 | 
| commit | 85d7b857fb8ca8e3c03d4abb3368a0966760630c (patch) | |
| tree | a16163e557bcae3af41bde7d2d771d64ca248a97 /bitlbee.c | |
| parent | 875ad4201402b1a8f80ba22a6cdcdb152c6e5510 (diff) | |
| parent | dd345753c1742905c9f81aa71d8b09109fbc5456 (diff) | |
Merge trunk.
Diffstat (limited to 'bitlbee.c')
| -rw-r--r-- | bitlbee.c | 124 | 
1 files changed, 63 insertions, 61 deletions
| @@ -33,56 +33,58 @@  #include <stdio.h>  #include <errno.h> -gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ); +static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition condition );  int bitlbee_daemon_init()  { -#ifdef IPV6 -	struct sockaddr_in6 listen_addr; -#else -	struct sockaddr_in listen_addr; -#endif +	struct addrinfo *res, hints, *addrinfo_bind;  	int i; -	GIOChannel *ch;  	FILE *fp;  	log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );  	log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG ); -	global.listen_socket = socket( AF_INETx, SOCK_STREAM, 0 ); -	if( global.listen_socket == -1 ) -	{ -		log_error( "socket" ); -		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 ); -	i = inet_pton( AF_INETx, ipv6_wrap( global.conf->iface ), &listen_addr.sin6_addr ); -#else -	listen_addr.sin_family = AF_INETx; -	listen_addr.sin_port = htons( global.conf->port ); -	i = inet_pton( AF_INETx, global.conf->iface, &listen_addr.sin_addr ); +	memset( &hints, 0, sizeof( hints ) ); +	hints.ai_family = PF_UNSPEC; +	hints.ai_socktype = SOCK_STREAM; +	hints.ai_flags = AI_PASSIVE +#ifdef AI_ADDRCONFIG +	               | AI_ADDRCONFIG  #endif -	 -	if( i != 1 ) +	; + +	i = getaddrinfo( global.conf->iface, global.conf->port, &hints, &addrinfo_bind ); +	if( i )  	{ -		log_message( LOGLVL_ERROR, "Couldn't parse address `%s'", global.conf->iface ); -		return( -1 ); +		log_message( LOGLVL_ERROR, "Couldn't parse address `%s': %s", +		                           global.conf->iface, gai_strerror(i) ); +		return -1;  	} -	 -	i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) ); -	if( i == -1 ) + +	global.listen_socket = -1; + +	for( res = addrinfo_bind; res; res = res->ai_next )  	{ -		log_error( "bind" ); -		return( -1 ); +		global.listen_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol ); +		if( global.listen_socket < 0 ) +			continue; + +		/* TIME_WAIT (?) sucks.. */ +		i = 1; +		setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) ); + +		i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen ); +		if( i == -1 ) +		{ +			log_error( "bind" ); +			return( -1 ); +		} + +		break;  	} -	 + +	freeaddrinfo( addrinfo_bind ); +  	i = listen( global.listen_socket, 10 );  	if( i == -1 )  	{ @@ -90,8 +92,7 @@ int bitlbee_daemon_init()  		return( -1 );  	} -	ch = g_io_channel_unix_new( global.listen_socket ); -	global.listen_watch_source_id = g_io_add_watch( ch, G_IO_IN, bitlbee_io_new_client, NULL ); +	global.listen_watch_source_id = b_input_add( global.listen_socket, GAIM_INPUT_READ, bitlbee_io_new_client, NULL );  #ifndef _WIN32  	if( !global.conf->nofork ) @@ -118,8 +119,7 @@ int bitlbee_daemon_init()  	if( global.conf->runmode == RUNMODE_FORKDAEMON )  		ipc_master_load_state(); -	if( global.conf->runmode == RUNMODE_DAEMON ||  -		global.conf->runmode == RUNMODE_FORKDAEMON ) +	if( global.conf->runmode == RUNMODE_DAEMON || global.conf->runmode == RUNMODE_FORKDAEMON )  		ipc_master_listen_socket();  #ifndef _WIN32 @@ -145,18 +145,12 @@ int bitlbee_inetd_init()  	return( 0 );  } -gboolean bitlbee_io_current_client_read( GIOChannel *source, GIOCondition condition, gpointer data ) +gboolean bitlbee_io_current_client_read( gpointer data, gint fd, b_input_condition cond )  {  	irc_t *irc = data;  	char line[513];  	int st; -	if( condition & G_IO_ERR || condition & G_IO_HUP ) -	{ -		irc_abort( irc, 1, "Read error" ); -		return FALSE; -	} -	  	st = read( irc->fd, line, sizeof( line ) - 1 );  	if( st == 0 )  	{ @@ -192,7 +186,7 @@ gboolean bitlbee_io_current_client_read( GIOChannel *source, GIOCondition condit  	/* Normally, irc_process() shouldn't call irc_free() but irc_abort(). Just in case: */  	if( !g_slist_find( irc_connection_list, irc ) )  	{ -		log_message( LOGLVL_WARNING, "Abnormal termination of connection with fd %d.", irc->fd ); +		log_message( LOGLVL_WARNING, "Abnormal termination of connection with fd %d.", fd );  		return FALSE;  	}  @@ -206,14 +200,14 @@ gboolean bitlbee_io_current_client_read( GIOChannel *source, GIOCondition condit  	return TRUE;  } -gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condition, gpointer data ) +gboolean bitlbee_io_current_client_write( gpointer data, gint fd, b_input_condition cond )  {  	irc_t *irc = data;  	int st, size;  	char *temp;  	if( irc->sendbuffer == NULL ) -		return( FALSE ); +		return FALSE;  	size = strlen( irc->sendbuffer );  	st = write( irc->fd, irc->sendbuffer, size ); @@ -234,10 +228,10 @@ gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condi  		irc->sendbuffer = NULL;  		irc->w_watch_source_id = 0; -		if( irc->status == USTATUS_SHUTDOWN ) +		if( irc->status & USTATUS_SHUTDOWN )  			irc_free( irc ); -		return( FALSE ); +		return FALSE;  	}  	else  	{ @@ -245,13 +239,13 @@ gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condi  		g_free( irc->sendbuffer );  		irc->sendbuffer = temp; -		return( TRUE ); +		return TRUE;  	}  } -gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ) +static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition condition )  { -	size_t size = sizeof( struct sockaddr_in ); +	socklen_t size = sizeof( struct sockaddr_in );  	struct sockaddr_in conn_info;  	int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size ); @@ -285,10 +279,10 @@ gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpoi  			child = g_new0( struct bitlbee_child, 1 );  			child->pid = client_pid;  			child->ipc_fd = fds[0]; -			child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child ); +			child->ipc_inpa = b_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );  			child_list = g_slist_append( child_list, child ); -			log_message( LOGLVL_INFO, "Creating new subprocess with pid %d.", client_pid ); +			log_message( LOGLVL_INFO, "Creating new subprocess with pid %d.", (int) client_pid );  			/* Close some things we don't need in the parent process. */  			close( new_socket ); @@ -298,16 +292,22 @@ gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpoi  		{  			irc_t *irc; +			/* Since we're fork()ing here, let's make sure we won't +			   get the same random numbers as the parent/siblings. */ +			srand( time( NULL ) ^ getpid() ); +			 +			b_main_init(); +			  			/* Close the listening socket, we're a client. */  			close( global.listen_socket ); -			g_source_remove( global.listen_watch_source_id ); +			b_event_remove( global.listen_watch_source_id );  			/* Make the connection. */  			irc = irc_new( new_socket );  			/* We can store the IPC fd there now. */  			global.listen_socket = fds[1]; -			global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc ); +			global.listen_watch_source_id = b_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc );  			close( fds[0] ); @@ -324,12 +324,14 @@ gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpoi  	return TRUE;  } -void bitlbee_shutdown( gpointer data ) +gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond )  {  	/* Try to save data for all active connections (if desired). */  	while( irc_connection_list != NULL )  		irc_free( irc_connection_list->data );  	/* We'll only reach this point when not running in inetd mode: */ -	g_main_quit( global.loop ); +	b_main_quit(); +	 +	return FALSE;  } | 
