Beispiel #1
0
void quit_do_cleanup(void)
{
  log_write("#############################################################################\n");
  log_command(LOG_SERVICES, NULL, "", "Services shutdown\n\n");

  debug_out("==> Starting onexit cleanup...\n");
  debug_out(" |==> Closing all sockets and freeing them...\n");
  com_free_all();           /* Close ALL connections and free memory */
  debug_out(" |==> Executing pending mySQL queries...\n");
  queue_wait_until_empty(); /* Make the queue write all the pending data to mySQL before quitting */
  debug_out(" |==> Freeing memory used by databases...\n");
  help_free();
  dbase_clear();            /* Clear the dbase and free memory */
  debug_out(" |==> Flushing and closing log files...\n");
  log_close();              /* flush and close log files */
  debug_out(" |==> Freeing memory used by settings...\n");
  conf_unload();            /* free memory taken by config */
  debug_out(" |==> Freeing memory used by timers...\n");
  timer_freeall();          /* remove all timers */
  debug_out(" \\==> Cleanup done, quitting...\n");
}
Beispiel #2
0
int main( int argc, char *argv[] )
{
	int i = 0;
	char *old_cwd = NULL;
	struct sigaction sig, old;
	
	/* Required to make iconv to ASCII//TRANSLIT work. This makes BitlBee
	   system-locale-sensitive. :-( */
	setlocale( LC_CTYPE, "" );
	
	if( argc > 1 && strcmp( argv[1], "-x" ) == 0 )
		return crypt_main( argc, argv );
	
	log_init();
	
	global.conf_file = g_strdup( CONF_FILE_DEF );
	global.conf = conf_load( argc, argv );
	if( global.conf == NULL )
		return( 1 );
	
	b_main_init();
	
	/* libpurple doesn't like fork()s after initializing itself, so if
	   we use it, do this init a little later (in case we're running in
	   ForkDaemon mode). */
#ifndef WITH_PURPLE
	nogaim_init();
#endif
	
 	/* Ugly Note: libotr and gnutls both use libgcrypt. libgcrypt
 	   has a process-global config state whose initialization happpens
 	   twice if libotr and gnutls are used together. libotr installs custom
 	   memory management functions for libgcrypt while our gnutls module
 	   uses the defaults. Therefore we initialize OTR after SSL. *sigh* */
 	ssl_init();
#ifdef OTR_BI
 	otr_init();
#endif
	/* And in case OTR is loaded as a plugin, it'll also get loaded after
	   this point. */
	
	srand( time( NULL ) ^ getpid() );
	
	global.helpfile = g_strdup( HELP_FILE );
	if( help_init( &global.help, global.helpfile ) == NULL )
		log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE );

	global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );
	if( global.storage == NULL )
	{
		log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage );
		return( 1 );
	}
	
	if( global.conf->runmode == RUNMODE_INETD )
	{
		log_link( LOGLVL_ERROR, LOGOUTPUT_IRC );
		log_link( LOGLVL_WARNING, LOGOUTPUT_IRC );
	
		i = bitlbee_inetd_init();
		log_message( LOGLVL_INFO, "%s %s starting in inetd mode.", PACKAGE, BITLBEE_VERSION );

	}
	else if( global.conf->runmode == RUNMODE_DAEMON )
	{
		log_link( LOGLVL_ERROR, LOGOUTPUT_CONSOLE );
		log_link( LOGLVL_WARNING, LOGOUTPUT_CONSOLE );

		i = bitlbee_daemon_init();
		log_message( LOGLVL_INFO, "%s %s starting in daemon mode.", PACKAGE, BITLBEE_VERSION );
	}
	else if( global.conf->runmode == RUNMODE_FORKDAEMON )
	{
		log_link( LOGLVL_ERROR, LOGOUTPUT_CONSOLE );
		log_link( LOGLVL_WARNING, LOGOUTPUT_CONSOLE );

		/* In case the operator requests a restart, we need this. */
		old_cwd = g_malloc( 256 );
		if( getcwd( old_cwd, 255 ) == NULL )
		{
			log_message( LOGLVL_WARNING, "Could not save current directory: %s", strerror( errno ) );
			g_free( old_cwd );
			old_cwd = NULL;
		}
		
		i = bitlbee_daemon_init();
		log_message( LOGLVL_INFO, "%s %s starting in forking daemon mode.", PACKAGE, BITLBEE_VERSION );
	}
	if( i != 0 )
		return( i );
	
	if( ( global.conf->user && *global.conf->user ) &&
	    ( global.conf->runmode == RUNMODE_DAEMON || 
	      global.conf->runmode == RUNMODE_FORKDAEMON ) &&
	    ( !getuid() || !geteuid() ) )
	{
		struct passwd *pw = NULL;
		pw = getpwnam( global.conf->user );
		if( pw )
		{
			initgroups( global.conf->user, pw->pw_gid );
			setgid( pw->pw_gid );
			setuid( pw->pw_uid );
		}
		else
		{
			log_message( LOGLVL_WARNING, "Failed to look up user %s.", global.conf->user );
		}
	}
 	
	/* Catch some signals to tell the user what's happening before quitting */
	memset( &sig, 0, sizeof( sig ) );
	sig.sa_handler = sighandler;
	sigaction( SIGCHLD, &sig, &old );
	sigaction( SIGPIPE, &sig, &old );
	sig.sa_flags = SA_RESETHAND;
	sigaction( SIGINT,  &sig, &old );
	sigaction( SIGILL,  &sig, &old );
	sigaction( SIGBUS,  &sig, &old );
	sigaction( SIGFPE,  &sig, &old );
	sigaction( SIGSEGV, &sig, &old );
	sigaction( SIGTERM, &sig, &old );
	sigaction( SIGQUIT, &sig, &old );
	sigaction( SIGXCPU, &sig, &old );
	
	if( !getuid() || !geteuid() )
		log_message( LOGLVL_WARNING, "BitlBee is running with root privileges. Why?" );
	
	b_main_run();
	
	/* Mainly good for restarting, to make sure we close the help.txt fd. */
	help_free( &global.help );
	
	if( global.restart )
	{
		char *fn = ipc_master_save_state();
		char *env;
		
		env = g_strdup_printf( "_BITLBEE_RESTART_STATE=%s", fn );
		putenv( env );
		g_free( fn );
		/* Looks like env should *not* be freed here as putenv
		   doesn't make a copy. Odd. */
		
		i = chdir( old_cwd );
		close( global.listen_socket );
		
		if( execv( argv[0], argv ) == -1 )
			/* Apparently the execve() failed, so let's just
			   jump back into our own/current main(). */
			/* Need more cleanup code to make this work. */
			return 1; /* main( argc, argv ); */
	}
	
	return( 0 );
}