source: lib/ini.c @ 2a6da96

Last change on this file since 2a6da96 was 0182773, checked in by Wilmer van der Gaast <wilmer@…>, at 2009-07-20T13:42:11Z

Fixed fd leak in ini.c. How could I miss this one.. :-(

  • 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-2008 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* INI file reading code                                                */
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#define BITLBEE_CORE
26#include "bitlbee.h"
27
28ini_t *ini_open( char *file )
29{
30        int fd;
31        ini_t *ini = NULL;
32        struct stat fi;
33       
34        if( ( fd = open( file, O_RDONLY ) ) != -1 &&
35            fstat( fd, &fi ) == 0 &&
36            fi.st_size <= 16384 &&
37            ( ini = g_malloc( sizeof( ini_t ) + fi.st_size + 1 ) ) &&
38            read( fd, ini->file, fi.st_size ) == fi.st_size )
39        {
40                memset( ini, 0, sizeof( ini_t ) );
41                ini->size = fi.st_size;
42                ini->file[ini->size] = 0;
43                ini->cur = ini->file;
44                ini->c_section = "";
45               
46                close( fd );
47               
48                return ini;
49        }
50
51        if( fd >= 0 )
52                close( fd );
53       
54        ini_close( ini );
55
56        return NULL;
57}
58
59/* Strips leading and trailing whitespace and returns a pointer to the first
60   non-ws character of the given string. */
61static char *ini_strip_whitespace( char *in )
62{
63        char *e;
64
65        while( isspace( *in ) )
66                in++;
67
68        e = in + strlen( in ) - 1;
69        while( e > in && isspace( *e ) )
70                e--;
71        e[1] = 0;
72       
73        return in;
74}
75
76int ini_read( ini_t *file )
77{
78        char *s;
79       
80        while( file->cur && file->cur < file->file + file->size )
81        {
82                char *e, *next;
83               
84                file->line++;
85
86                /* Find the end of line */
87                if( ( e = strchr( file->cur, '\n' ) ) != NULL )
88                {
89                        *e = 0;
90                        next = e + 1;
91                }
92                else
93                {
94                        /* No more lines. */
95                        e = file->cur + strlen( file->cur );
96                        next = NULL;
97                }
98               
99                /* Comment? */
100                if( ( s = strchr( file->cur, '#' ) ) != NULL )
101                        *s = 0;
102               
103                file->cur = ini_strip_whitespace( file->cur );
104               
105                if( *file->cur == '[' )
106                {
107                        file->cur++;
108                        if( ( s = strchr( file->cur, ']' ) ) != NULL )
109                        {
110                                *s = 0;
111                                file->c_section = file->cur;
112                        }
113                }
114                else if( ( s = strchr( file->cur, '=' ) ) != NULL )
115                {
116                        *s = 0;
117                        file->key = ini_strip_whitespace( file->cur );
118                        file->value = ini_strip_whitespace( s + 1 );
119                       
120                        if( ( s = strchr( file->key, '.' ) ) != NULL )
121                        {
122                                *s = 0;
123                                file->section = file->key;
124                                file->key = s + 1;
125                        }
126                        else
127                        {
128                                file->section = file->c_section;
129                        }
130                       
131                        file->cur = next;
132                        return 1;
133                }
134                /* else: noise/comment/etc, let's just ignore it. */
135
136                file->cur = next;
137        }
138       
139        return 0;
140}
141
142void ini_close( ini_t *file )
143{
144        g_free( file );
145}
Note: See TracBrowser for help on using the repository browser.