]> git.deb.at Git - pkg/abook.git/blob - conff.c
Initial revision
[pkg/abook.git] / conff.c
1
2 /*
3  *
4  *  conff.c by JH <jheinonen@bigfoot.com>
5  *
6  *  Copyright (C) Jaakko Heinonen
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */
22
23 /*
24  * conff.c version 0.3.0
25  */
26
27 #include <stdio.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include "misc.h"
32 #ifdef HAVE_CONFIG_H
33 #       include "config.h"
34 #endif
35 #include "conff.h"
36
37 #ifndef DEBUG
38 #       define NDEBUG   1
39 #else
40 #       undef NDEBUG
41 #endif
42
43 #include <assert.h>
44
45 #ifdef _AIX
46 int strcasecmp (const char *, const char *);
47 int strncasecmp (const char *, const char *, size_t);
48 #endif
49
50 #define COMMENT_CHAR    '#'
51
52 static void
53 conff_free_node(struct conff_node *node)
54 {
55         free(node -> value);
56         free(node -> key);
57         free(node);
58 }
59
60 void
61 conff_add_key(struct conff_node **ptr, char *key, char *value, int flags)
62 {
63         struct conff_node *new_item, *next = NULL;
64
65         assert(key != NULL && value != NULL);
66
67         for(; *ptr; ptr = &( (*ptr) -> next) ) 
68                 if(!strcasecmp(key, (*ptr) -> key ) ) {
69                         if (flags & REPLACE_KEY) {
70                                 next = (*ptr) -> next;
71                                 conff_free_node(*ptr);
72                                 break;
73                         } else
74                                 return;
75                 }
76         
77          /*
78           * out of memory - error is ingnored
79           * NOTE: with REPLACE_KEY flag the node will be deleted in OOM
80           * situation
81           */
82         if( (new_item = malloc(sizeof(struct conff_node))) == NULL )
83                 return;
84         
85         new_item -> key = strdup(key);
86         new_item -> value = strdup(value);
87         new_item -> next = next;
88
89         *ptr = new_item;
90 }
91
92 char *
93 conff_get_value(struct conff_node *node, char *key)
94 {
95
96         assert(key != NULL);
97         
98         for(; node ; node = node -> next) {
99                 if(!strcasecmp(node -> key, key))
100                         return node -> value;
101         }
102
103         return NULL; /* not found */
104 }
105
106 void
107 conff_free_nodes(struct conff_node *node)
108 {
109         if(node != NULL) {
110                 conff_free_nodes( node -> next );
111                 conff_free_node( node );
112         }
113 }
114
115 #ifdef DEBUG
116 void
117 print_values(struct conff_node *node)
118 {
119         for(;node; node = node -> next)
120                 fprintf(stderr, "%s - %s\n", node -> key, node -> value);
121 }
122 #endif
123
124 void
125 conff_remove_key(struct conff_node **node, char *key)
126 {
127         assert(key != NULL);
128         
129         for(; *node; node = &((*node) -> next) ) {
130                 if(!strcasecmp(key, (*node) -> key ) ) {
131                         struct conff_node *tmp = *node;
132                         *node = (*node) -> next;
133                         conff_free_node(tmp);
134                         return;
135                 }
136         }
137 }
138
139 int
140 conff_save_file(struct conff_node *node, char *filename)
141 {
142         FILE *out;
143
144         assert(filename != NULL);
145
146         if (!(out = fopen(filename, "w")))
147                 return -1;
148
149         for(; node; node = node -> next)
150                 fprintf(out, "%s=%s\n", node -> key, node -> value);
151
152         fputc('\n', out);
153         fclose(out);
154
155         return 0;
156 }
157
158 int
159 conff_load_file(struct conff_node **node, char *filename, int flags)
160 {
161         FILE *in;
162         char *line = NULL, *tmp;
163         int i = 0;
164
165         if (!(in = fopen(filename, "r")))
166                 return -1;
167
168         for(;;) {
169                 i++;
170
171                 line = getaline(in);
172                 if( feof(in) )
173                         break;
174                 if(!line)
175                         continue;
176
177                 strtrim(line);
178
179                 if(*line == '\n' || *line == '\0' || *line == COMMENT_CHAR) {
180                         free(line);
181                         continue;
182                 }
183
184                 if ( (tmp = strchr(line, '=') )) {
185                         *tmp++ = 0;
186                         conff_add_key(node, strtrim(line), strtrim(tmp), flags);
187                 } else {
188 /*                      fprintf(stderr, "parse error2,line #%d\n",i);*/
189                         fclose(in);
190                         free(line);
191                         return i;
192                 }
193                 free(line);
194         }
195
196         free(line);
197         fclose(in);
198
199         return 0;
200 }
201