aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--help.c66
-rw-r--r--help.h5
-rw-r--r--irc.c11
-rw-r--r--irc.h1
-rw-r--r--irc_commands.c2
-rw-r--r--unix.c5
6 files changed, 53 insertions, 37 deletions
diff --git a/help.c b/help.c
index 756eb12a..587b9940 100644
--- a/help.c
+++ b/help.c
@@ -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 );
}
diff --git a/help.h b/help.h
index 32aba723..5421220c 100644
--- a/help.h
+++ b/help.h
@@ -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
diff --git a/irc.c b/irc.c
index 972e030e..2510e3d9 100644
--- a/irc.c
+++ b/irc.c
@@ -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 )
diff --git a/irc.h b/irc.h
index 8be3579e..eb70ad1c 100644
--- a/irc.h
+++ b/irc.h
@@ -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 );
diff --git a/unix.c b/unix.c
index 0aaf505a..9b670d78 100644
--- a/unix.c
+++ b/unix.c
@@ -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();