source: help.c @ f3597a1

Last change on this file since f3597a1 was c227706, checked in by Jelmer Vernooij <jelmer@…>, at 2006-12-24T19:35:13Z

Refactor the help code to take a filename rather than using the global struct.

  • Property mode set to 100644
File size: 3.2 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2005 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* Help file control                                                    */
8
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.
14
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.
19
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
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
28#undef read
29#undef write
30
31#define BUFSIZE 1100
32
33help_t *help_init( help_t **help, const char *helpfile )
34{
35        int i, buflen = 0;
36        help_t *h;
37        char *s, *t;
38        time_t mtime;
39        struct stat stat[1];
40       
41        *help = h = g_new0 ( help_t, 1 );
42       
43        h->fd = open( helpfile, O_RDONLY
44#ifdef _WIN32
45                                  | O_BINARY
46#endif
47                                  );
48       
49        if( h->fd == -1 )
50        {
51                g_free( h );
52                return( *help = NULL );
53        }
54       
55        if( fstat( h->fd, stat ) != 0 )
56        {
57                g_free( h );
58                return( *help = NULL );
59        }
60        mtime = stat->st_mtime;
61       
62        s = g_new (char, BUFSIZE + 1 );
63        s[BUFSIZE] = 0;
64       
65        while( ( ( i = read( h->fd, s + buflen, BUFSIZE - buflen ) ) > 0 ) ||
66               ( i == 0 && strstr( s, "\n%\n" ) ) )
67        {
68                buflen += i;
69                memset( s + buflen, 0, BUFSIZE - buflen );
70                if( !( t = strstr( s, "\n%\n" ) ) || s[0] != '?' )
71                {
72                        /* FIXME: Clean up */
73//                      help_close( *help );
74                        *help = NULL;
75                        g_free( s );
76                        return( NULL );
77                }
78                i = strchr( s, '\n' ) - s;
79               
80                if( h->string )
81                {
82                        h = h->next = g_new0( help_t, 1 );
83                }
84                h->string = g_new ( char, i );
85               
86                strncpy( h->string, s + 1, i - 1 );
87                h->string[i-1] = 0;
88                h->fd = (*help)->fd;
89                h->offset.file_offset = lseek( h->fd, 0, SEEK_CUR ) - buflen + i + 1;
90                h->length = t - s - i - 1;
91                h->mtime = mtime;
92               
93                buflen -= ( t + 3 - s );
94                t = g_strdup( t + 3 );
95                g_free( s );
96                s = g_renew( char, t, BUFSIZE + 1 );
97                s[BUFSIZE] = 0;
98        }
99       
100        g_free( s );
101       
102        return( *help );
103}
104
105char *help_get( help_t **help, char *string )
106{
107        time_t mtime;
108        struct stat stat[1];
109        help_t *h;
110
111        for( h = *help; h; h = h->next )
112        {
113                if( h->string != NULL && 
114                        g_strcasecmp( h->string, string ) == 0 ) 
115                        break;
116        }
117        if( h && h->length > 0 )
118        {
119                char *s = g_new( char, h->length + 1 );
120               
121                if( fstat( h->fd, stat ) != 0 )
122                {
123                        g_free( h );
124                        *help = NULL;
125                        return NULL;
126                }
127                mtime = stat->st_mtime;
128               
129                if( mtime > h->mtime )
130                        return NULL;
131               
132                s[h->length] = 0;
133                if( h->fd >= 0 )
134                {
135                        lseek( h->fd, h->offset.file_offset, SEEK_SET );
136                        read( h->fd, s, h->length );
137                }
138                else
139                {
140                        strncpy( s, h->offset.mem_offset, h->length );
141                }
142                return s;
143        }
144       
145        return NULL;
146}
Note: See TracBrowser for help on using the repository browser.