diff options
| -rw-r--r-- | help.c | 66 | ||||
| -rw-r--r-- | help.h | 5 | ||||
| -rw-r--r-- | irc.c | 11 | ||||
| -rw-r--r-- | irc.h | 1 | ||||
| -rw-r--r-- | irc_commands.c | 2 | ||||
| -rw-r--r-- | unix.c | 5 | 
6 files changed, 53 insertions, 37 deletions
| @@ -70,21 +70,20 @@ help_t *help_init( help_t **help, const char *helpfile )  		if( !( t = strstr( s, "\n%\n" ) ) || s[0] != '?' )  		{  			/* FIXME: Clean up */ -//			help_close( *help ); -			*help = NULL; +			help_free( help );  			g_free( s ); -			return( NULL ); +			return NULL;  		}  		i = strchr( s, '\n' ) - s; -		if( h->string ) +		if( h->title )  		{  			h = h->next = g_new0( help_t, 1 );  		} -		h->string = g_new ( char, i ); +		h->title = g_new ( char, i ); -		strncpy( h->string, s + 1, i - 1 ); -		h->string[i-1] = 0; +		strncpy( h->title, s + 1, i - 1 ); +		h->title[i-1] = 0;  		h->fd = (*help)->fd;  		h->offset.file_offset = lseek( h->fd, 0, SEEK_CUR ) - buflen + i + 1;  		h->length = t - s - i - 1; @@ -102,7 +101,31 @@ help_t *help_init( help_t **help, const char *helpfile )  	return( *help );  } -char *help_get( help_t **help, char *string ) +void help_free( help_t **help ) +{ +	help_t *h, *oh; +	int last_fd = -1; /* Weak de-dupe */ +	 +	if( help == NULL || *help == NULL ) +		return; +	 +	h = *help; +	while( h ) +	{ +		if( h->fd != last_fd ) +		{ +			close( h->fd ); +			last_fd = h->fd; +		} +		g_free( h->title ); +		h = (oh=h)->next; +		g_free( oh ); +	} +	 +	*help = NULL; +} + +char *help_get( help_t **help, char *title )  {  	time_t mtime;  	struct stat stat[1]; @@ -110,28 +133,29 @@ char *help_get( help_t **help, char *string )  	for( h = *help; h; h = h->next )  	{ -		if( h->string != NULL &&  -			g_strcasecmp( h->string, string ) == 0 )  +		if( h->title != NULL && g_strcasecmp( h->title, title ) == 0 )  			break;  	}  	if( h && h->length > 0 )  	{  		char *s = g_new( char, h->length + 1 ); -		if( fstat( h->fd, stat ) != 0 ) -		{ -			g_free( h ); -			*help = NULL; -			return NULL; -		} -		mtime = stat->st_mtime; -		 -		if( mtime > h->mtime ) -			return NULL; -		  		s[h->length] = 0;  		if( h->fd >= 0 )  		{ +			if( fstat( h->fd, stat ) != 0 ) +			{ +				g_free( s ); +				return NULL; +			} +			mtime = stat->st_mtime; +		 +			if( mtime > h->mtime ) +			{ +				g_free( s ); +				return NULL; +			} +			  			lseek( h->fd, h->offset.file_offset, SEEK_SET );  			read( h->fd, s, h->length );  		} @@ -36,13 +36,14 @@ typedef struct help  {  	int fd;  	time_t mtime; -	char *string; +	char *title;  	help_off_t offset;  	int length;  	struct help *next;  } help_t;  G_GNUC_MALLOC help_t *help_init( help_t **help, const char *helpfile ); -char *help_get( help_t **help, char *string ); +void help_free( help_t **help ); +char *help_get( help_t **help, char *title );  #endif @@ -188,7 +188,6 @@ void irc_free(irc_t * irc)  {  	account_t *account;  	user_t *user, *usertmp; -	help_t *helpnode, *helpnodetmp;  	log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); @@ -265,16 +264,6 @@ void irc_free(irc_t * irc)  	g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL);  	g_hash_table_destroy(irc->watches); -	if (irc->help != NULL) { -		helpnode = irc->help; -		while (helpnode != NULL) { -			g_free(helpnode->string); -			 -			helpnodetmp = helpnode; -			helpnode = helpnode->next; -			g_free(helpnodetmp); -		} -	}  	g_free(irc);  	if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) @@ -88,7 +88,6 @@ typedef struct irc  	GHashTable *userhash;  	GHashTable *watches;  	struct __NICK *nicks; -	struct help *help;  	struct set *set;  	gint r_watch_source_id; diff --git a/irc_commands.c b/irc_commands.c index 65f0d6c6..4b431027 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -555,7 +555,7 @@ static void irc_cmd_completions( irc_t *irc, char **cmd )  		irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command );  	for( h = global.help; h; h = h->next ) -		irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->string ); +		irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->title );  	for( s = irc->set; s; s = s->next )  		irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key ); @@ -123,11 +123,14 @@ int main( int argc, char *argv[], char **envp )  	if( !getuid() || !geteuid() )  		log_message( LOGLVL_WARNING, "BitlBee is running with root privileges. Why?" ); -	if( help_init( &(global.help), global.helpfile ) == NULL ) +	if( help_init( &global.help, global.helpfile ) == NULL )  		log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE );  	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(); | 
