]> git.deb.at Git - pkg/abook.git/blob - conff.c
added 0.4.16 release
[pkg/abook.git] / conff.c
1
2 /*
3  *
4  * $Id$
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 #include <stdio.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include "misc.h"
28 #ifdef HAVE_CONFIG_H
29 #       include "config.h"
30 #endif
31 #include "conff.h"
32
33 #ifndef DEBUG
34 #       define NDEBUG   1
35 #else
36 #       undef NDEBUG
37 #endif
38
39 #include <assert.h>
40
41 #ifdef _AIX
42 int strcasecmp (const char *, const char *);
43 int strncasecmp (const char *, const char *, size_t);
44 #endif
45
46 #define COMMENT_CHAR    '#'
47
48 static void
49 conff_free_node(struct conff_node *node)
50 {
51         free(node -> value);
52         free(node -> key);
53         free(node);
54 }
55
56 /*
57  * conff_add_key
58  *
59  * returns 0 if the key was successfully added
60  */
61
62 int
63 conff_add_key(struct conff_node **ptr, char *key, char *value, int flags)
64 {
65         struct conff_node *new_item, *next = NULL;
66         int replace = 0;
67
68         assert(key != NULL && value != NULL);
69
70         for(; *ptr; ptr = &( (*ptr) -> next) ) 
71                 if(!strcasecmp(key, (*ptr) -> key ) ) {
72                         if (flags & REPLACE_KEY) {
73                                 replace = 1;
74                                 break;
75                         } else
76                                 return 1;
77                 }
78         
79         if( (new_item = (struct conff_node *)malloc(sizeof(struct conff_node)))
80                         == NULL )
81                 return 5;
82
83         if(replace) { 
84                 next = (*ptr) -> next;
85                 conff_free_node(*ptr);
86         }
87
88         new_item -> key = strdup(key);
89         new_item -> value = strdup(value);
90         new_item -> next = next;
91
92         *ptr = new_item;
93
94         return 0;
95 }
96
97 char *
98 conff_get_value(struct conff_node *node, char *key)
99 {
100
101         assert(key != NULL);
102         
103         for(; node ; node = node -> next) {
104                 if(!strcasecmp(node -> key, key))
105                         return node -> value;
106         }
107
108         return NULL; /* not found */
109 }
110
111 void
112 conff_free_nodes(struct conff_node *node)
113 {
114         if(node != NULL) {
115                 conff_free_nodes( node -> next );
116                 conff_free_node( node );
117         }
118 }
119
120 #ifdef DEBUG
121 void
122 print_values(struct conff_node *node)
123 {
124         for(;node; node = node -> next)
125                 fprintf(stderr, "%s - %s\n", node -> key, node -> value);
126 }
127 #endif
128
129 void
130 conff_remove_key(struct conff_node **node, char *key)
131 {
132         assert(key != NULL);
133         
134         for(; *node; node = &((*node) -> next) ) {
135                 if(!strcasecmp(key, (*node) -> key ) ) {
136                         struct conff_node *tmp = *node;
137                         *node = (*node) -> next;
138                         conff_free_node(tmp);
139                         return;
140                 }
141         }
142 }
143
144 int
145 conff_save_file(struct conff_node *node, char *filename)
146 {
147         FILE *out;
148
149         assert(filename != NULL);
150
151         if (!(out = fopen(filename, "w")))
152                 return -1;
153
154         for(; node; node = node -> next)
155                 fprintf(out, "%s=%s\n", node -> key, node -> value);
156
157         fputc('\n', out);
158         fclose(out);
159
160         return 0;
161 }
162
163 int
164 conff_load_file(struct conff_node **node, char *filename, int flags)
165 {
166         FILE *in;
167         char *line = NULL, *tmp;
168         int i = 0;
169
170         assert(filename != NULL);
171
172         if (!(in = fopen(filename, "r")))
173                 return -1;
174
175         for(;;) {
176                 i++;
177
178                 line = getaline(in);
179                 if( feof(in) )
180                         break;
181                 if(!line)
182                         continue;
183
184                 strtrim(line);
185
186                 if(*line == '\n' || *line == '\0' || *line == COMMENT_CHAR) {
187                         free(line);
188                         continue;
189                 }
190
191                 if ( (tmp = strchr(line, '=') )) {
192                         *tmp++ = 0;
193                         conff_add_key(node, strtrim(line), strtrim(tmp), flags);
194                 } else {
195 /*                      fprintf(stderr, "parse error2,line #%d\n",i);*/
196                         fclose(in);
197                         free(line);
198                         return i;
199                 }
200                 free(line);
201         }
202
203         free(line);
204         fclose(in);
205
206         return 0;
207 }
208