source: help.c @ 5bcf70a

Last change on this file since 5bcf70a was 022e77f, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-03-06T12:15:46Z

Fixed error handling on empty help topics. (See #109)

  • Property mode set to 100644
File size: 3.2 KB
RevLine 
[b7d3cc34]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
[c92e6801]4  * Copyright 2002-2005 Wilmer van der Gaast and others                *
[b7d3cc34]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 )
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( global.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        h=*help;       
112
113        while( h )
114        {
115                if( g_strcasecmp( h->string, string ) == 0 ) break;
116                h = h->next;
117        }
[022e77f]118        if( h && h->length > 0 )
[b7d3cc34]119        {
120                char *s = g_new( char, h->length + 1 );
121               
122                if( fstat( h->fd, stat ) != 0 )
123                {
124                        g_free( h );
[022e77f]125                        *help = NULL;
126                        return NULL;
[b7d3cc34]127                }
128                mtime = stat->st_mtime;
129               
[022e77f]130                if( mtime > h->mtime )
131                        return NULL;
132               
[b7d3cc34]133                s[h->length] = 0;
134                if( h->fd >= 0 )
135                {
136                        lseek( h->fd, h->offset.file_offset, SEEK_SET );
137                        read( h->fd, s, h->length );
138                }
139                else
140                {
141                        strncpy( s, h->offset.mem_offset, h->length );
142                }
[022e77f]143                return s;
[b7d3cc34]144        }
145       
[022e77f]146        return NULL;
[b7d3cc34]147}
Note: See TracBrowser for help on using the repository browser.