]> git.deb.at Git - pkg/abook.git/blob - conff.c
b9242934aba8de5112fc555e11683709160d1c2c
[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 void
57 conff_add_key(struct conff_node **ptr, char *key, char *value, int flags)
58 {
59         struct conff_node *new_item, *next = NULL;
60
61         assert(key != NULL && value != NULL);
62
63         for(; *ptr; ptr = &( (*ptr) -> next) ) 
64                 if(!strcasecmp(key, (*ptr) -> key ) ) {
65                         if (flags & REPLACE_KEY) {
66                                 next = (*ptr) -> next;
67                                 conff_free_node(*ptr);
68                                 break;
69                         } else
70                                 return;
71                 }
72         
73          /*
74           * out of memory - error is ignored
75           * NOTE: with REPLACE_KEY flag the node will be deleted in OOM
76           * situation
77           */
78         if( (new_item = malloc(sizeof(struct conff_node))) == NULL )
79                 return;
80         
81         new_item -> key = strdup(key);
82         new_item -> value = strdup(value);
83         new_item -> next = next;
84
85         *ptr = new_item;
86 }
87
88 char *
89 conff_get_value(struct conff_node *node, char *key)
90 {
91
92         assert(key != NULL);
93         
94         for(; node ; node = node -> next) {
95                 if(!strcasecmp(node -> key, key))
96                         return node -> value;
97         }
98
99         return NULL; /* not found */
100 }
101
102 void
103 conff_free_nodes(struct conff_node *node)
104 {
105         if(node != NULL) {
106                 conff_free_nodes( node -> next );
107                 conff_free_node( node );
108         }
109 }
110
111 #ifdef DEBUG
112 void
113 print_values(struct conff_node *node)
114 {
115         for(;node; node = node -> next)
116                 fprintf(stderr, "%s - %s\n", node -> key, node -> value);
117 }
118 #endif
119
120 void
121 conff_remove_key(struct conff_node **node, char *key)
122 {
123         assert(key != NULL);
124         
125         for(; *node; node = &((*node) -> next) ) {
126                 if(!strcasecmp(key, (*node) -> key ) ) {
127                         struct conff_node *tmp = *node;
128                         *node = (*node) -> next;
129                         conff_free_node(tmp);
130                         return;
131                 }
132         }
133 }
134
135 int
136 conff_save_file(struct conff_node *node, char *filename)
137 {
138         FILE *out;
139
140         assert(filename != NULL);
141
142         if (!(out = fopen(filename, "w")))
143                 return -1;
144
145         for(; node; node = node -> next)
146                 fprintf(out, "%s=%s\n", node -> key, node -> value);
147
148         fputc('\n', out);
149         fclose(out);
150
151         return 0;
152 }
153
154 int
155 conff_load_file(struct conff_node **node, char *filename, int flags)
156 {
157         FILE *in;
158         char *line = NULL, *tmp;
159         int i = 0;
160
161         if (!(in = fopen(filename, "r")))
162                 return -1;
163
164         for(;;) {
165                 i++;
166
167                 line = getaline(in);
168                 if( feof(in) )
169                         break;
170                 if(!line)
171                         continue;
172
173                 strtrim(line);
174
175                 if(*line == '\n' || *line == '\0' || *line == COMMENT_CHAR) {
176                         free(line);
177                         continue;
178                 }
179
180                 if ( (tmp = strchr(line, '=') )) {
181                         *tmp++ = 0;
182                         conff_add_key(node, strtrim(line), strtrim(tmp), flags);
183                 } else {
184 /*                      fprintf(stderr, "parse error2,line #%d\n",i);*/
185                         fclose(in);
186                         free(line);
187                         return i;
188                 }
189                 free(line);
190         }
191
192         free(line);
193         fclose(in);
194
195         return 0;
196 }
197