Debian package changelog entry.
[bitlbee.git] / help.c
blob587b9940b274f4764e2377ee5470028943de0cc7
1 /********************************************************************\
2 * BitlBee -- An IRC to other IM-networks gateway *
3 * *
4 * Copyright 2002-2005 Wilmer van der Gaast and others *
5 \********************************************************************/
7 /* Help file control */
9 /*
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License with
21 the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22 if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23 Suite 330, Boston, MA 02111-1307 USA
26 #define BITLBEE_CORE
27 #include "bitlbee.h"
28 #undef read
29 #undef write
31 #define BUFSIZE 1100
33 help_t *help_init( help_t **help, const char *helpfile )
35 int i, buflen = 0;
36 help_t *h;
37 char *s, *t;
38 time_t mtime;
39 struct stat stat[1];
41 *help = h = g_new0 ( help_t, 1 );
43 h->fd = open( helpfile, O_RDONLY
44 #ifdef _WIN32
45 | O_BINARY
46 #endif
49 if( h->fd == -1 )
51 g_free( h );
52 return( *help = NULL );
55 if( fstat( h->fd, stat ) != 0 )
57 g_free( h );
58 return( *help = NULL );
60 mtime = stat->st_mtime;
62 s = g_new (char, BUFSIZE + 1 );
63 s[BUFSIZE] = 0;
65 while( ( ( i = read( h->fd, s + buflen, BUFSIZE - buflen ) ) > 0 ) ||
66 ( i == 0 && strstr( s, "\n%\n" ) ) )
68 buflen += i;
69 memset( s + buflen, 0, BUFSIZE - buflen );
70 if( !( t = strstr( s, "\n%\n" ) ) || s[0] != '?' )
72 /* FIXME: Clean up */
73 help_free( help );
74 g_free( s );
75 return NULL;
77 i = strchr( s, '\n' ) - s;
79 if( h->title )
81 h = h->next = g_new0( help_t, 1 );
83 h->title = g_new ( char, i );
85 strncpy( h->title, s + 1, i - 1 );
86 h->title[i-1] = 0;
87 h->fd = (*help)->fd;
88 h->offset.file_offset = lseek( h->fd, 0, SEEK_CUR ) - buflen + i + 1;
89 h->length = t - s - i - 1;
90 h->mtime = mtime;
92 buflen -= ( t + 3 - s );
93 t = g_strdup( t + 3 );
94 g_free( s );
95 s = g_renew( char, t, BUFSIZE + 1 );
96 s[BUFSIZE] = 0;
99 g_free( s );
101 return( *help );
104 void help_free( help_t **help )
106 help_t *h, *oh;
107 int last_fd = -1; /* Weak de-dupe */
109 if( help == NULL || *help == NULL )
110 return;
112 h = *help;
113 while( h )
115 if( h->fd != last_fd )
117 close( h->fd );
118 last_fd = h->fd;
120 g_free( h->title );
121 h = (oh=h)->next;
122 g_free( oh );
125 *help = NULL;
128 char *help_get( help_t **help, char *title )
130 time_t mtime;
131 struct stat stat[1];
132 help_t *h;
134 for( h = *help; h; h = h->next )
136 if( h->title != NULL && g_strcasecmp( h->title, title ) == 0 )
137 break;
139 if( h && h->length > 0 )
141 char *s = g_new( char, h->length + 1 );
143 s[h->length] = 0;
144 if( h->fd >= 0 )
146 if( fstat( h->fd, stat ) != 0 )
148 g_free( s );
149 return NULL;
151 mtime = stat->st_mtime;
153 if( mtime > h->mtime )
155 g_free( s );
156 return NULL;
159 lseek( h->fd, h->offset.file_offset, SEEK_SET );
160 read( h->fd, s, h->length );
162 else
164 strncpy( s, h->offset.mem_offset, h->length );
166 return s;
169 return NULL;