http://prdownloads.sourceforge.net/lufs/lufs-0.9.6.tar.gz?download
[lufs.git] / lufsd / options.c
1 /*
2  * options.c
3  * Copyright (C) 2002 Florin Malita <mali@go.ro>
4  *
5  * This file is part of LUFS, a free userspace filesystem implementation.
6  * See http://lufs.sourceforge.net/ for updates.
7  *
8  * LUFS 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  * LUFS 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 <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <lufs/fs.h>
29
30 #include "list.h"
31
32 struct option {
33     char *key;
34     char *value;
35     struct list_head list;
36 };
37
38 struct domain {
39     char *name;
40     struct list_head properties;
41     struct list_head list;
42 };
43
44
45 static void
46 trim(char *buf){
47     int b,e;
48     
49     if(!buf[0])
50         return;
51
52     for(b = 0; (buf[b] == ' ') || (buf[b] == '\t'); b++);
53     for(e = strlen(buf) - 1; (e >= 0) && ((buf[e] == ' ') || (buf[e] == '\t')); e--);
54     if(e < 0)
55         e = strlen(buf) - 1;
56
57     buf[e + 1] = 0;
58     
59     if(b)
60         strcpy(buf, &buf[b]);
61
62 }
63
64 static struct domain*
65 find_domain(struct list_head *conf, char *name){
66     struct list_head *p;
67     struct domain *cls;
68
69     list_for_each(p, conf){
70         cls = list_entry(p, struct domain, list);
71         if(!strcmp(name, cls->name)){
72             TRACE("domain found");
73             return cls;
74         }
75     }
76
77     return NULL;
78 }
79
80 int
81 lu_opt_loadcfg(struct list_head *conf, char *file){
82     struct domain *class;
83     struct option *prop;
84     FILE *f;
85     static char buf[1024];
86     char *i, *j;
87     char *cls, *key, *val;
88
89     TRACE("loading config from %s", file);
90
91     if(!(f = fopen(file, "r"))){
92         WARN("could not open file for reading!");
93         return -1;
94     }
95
96     while(fgets(buf, 1024, f)){
97         
98         buf[strlen(buf) - 1] = 0;
99
100         if((i = strchr(buf, '#')))
101             *i = 0;
102         
103         if((i = strchr(buf, '='))){
104             if((j = strstr(buf, "::"))){
105                 cls = buf;
106                 key = j + 2;
107                 val = i + 1;
108                 
109                 *i = 0;
110                 *j = 0;
111
112                 trim(cls);
113                 trim(key);
114                 trim(val);
115
116                 TRACE("class: #%s#", cls);
117                 TRACE("key: #%s#", key);
118                 TRACE("val: #%s#", val);
119
120                 if(!(class = find_domain(conf, cls))){
121                     TRACE("class not found, creating...");
122
123                     if(!(class = malloc(sizeof(struct domain)))){
124                         WARN("out of mem!");
125                         break;
126                     }
127
128                     memset(class, 0, sizeof(struct domain));
129
130                     if(!(class->name = malloc(strlen(cls) + 1))){
131                         WARN("out of mem!");
132                         free(class);
133                         break;
134                     }
135
136                     strcpy(class->name, cls);
137                     INIT_LIST_HEAD(&class->properties);
138
139                     list_add(&class->list, conf);
140                 }
141
142                 if(!(prop = malloc(sizeof(struct option)))){
143                     WARN("out of mem!");
144                     break;
145                 }
146
147                 if(!(prop->key = malloc(strlen(key) + 1))){
148                     WARN("out of mem!");
149                     free(prop);
150                     break;
151                 }
152
153                 if(!(prop->value = malloc(strlen(val) + 1))){
154                     WARN("out of mem!");
155                     free(prop->key);
156                     free(prop);
157                     break;
158                 }
159
160                 strcpy(prop->key, key);
161                 strcpy(prop->value, val);
162                 
163                 list_add(&prop->list, &class->properties);
164             }
165         }
166         
167     }
168
169
170     fclose(f);
171
172     return 0;
173 }
174
175
176 const char*
177 lu_opt_getchar(struct list_head *conf, char *cls, char *key){
178     struct domain *class;
179     struct option *prop;
180     struct list_head *p;
181
182     TRACE("retrieving %s::%s", cls, key);
183     
184     if(!(class = find_domain(conf, cls)))
185         return NULL;
186
187     list_for_each(p, &class->properties){
188         prop = list_entry(p, struct option, list);
189
190         if(!strcmp(key, prop->key)){
191             TRACE("key found");
192             return prop->value;
193         }
194     }
195
196     TRACE("key not found");
197
198     return NULL;
199 }
200
201 int
202 lu_opt_getint(struct list_head *conf, char *domain, char *key, long int *result, int base){
203     char *end;
204     const char *val;
205     long int res;
206
207     if(!(val = lu_opt_getchar(conf, domain, key)))
208         return -1;
209     
210     res = strtol(val, &end, base);
211     
212     if(*end)
213         return -1;
214     
215     *result = res;
216     return 0;
217 }
218
219 int
220 lu_opt_parse(struct list_head *conf, char *domain, char *opts){
221     struct domain *class;
222     struct option *prop;
223     char *p, *sep;
224
225     if(!(class = find_domain(conf, domain))){
226         TRACE("domain not found, creating...");
227         
228         if(!(class = malloc(sizeof(struct domain)))){
229             WARN("out of mem!");
230             return -1;
231         }
232         
233         memset(class, 0, sizeof(struct domain));
234         
235         if(!(class->name = malloc(strlen(domain) + 1))){
236             WARN("out of mem!");
237             free(class);
238             return -1;
239         }
240         
241         strcpy(class->name, domain);
242         INIT_LIST_HEAD(&class->properties);
243         
244         list_add(&class->list, conf);
245     }
246     
247     for(p = strtok(opts, ","); p; p = strtok(NULL, ",")){
248         if(!strstr(p, "password"))
249             TRACE("option: %s", p);
250
251         if(!(prop = malloc(sizeof(struct option)))){
252             WARN("out of mem!");
253             return -1;
254         }
255
256         if((sep = strchr(p, '=')))
257             *sep = 0;
258
259         if(!(prop->key = malloc(strlen(p) + 1))){
260             WARN("out of mem!");
261             free(prop);
262             return -1;
263         }
264         strcpy(prop->key, p);
265
266         if(sep){
267             TRACE("option with parameter");
268
269             if((strlen(sep + 1) >= MAX_LEN) || !(prop->value = malloc(strlen(sep + 1) + 1))){
270                 WARN("out of mem!");
271                 free(prop->key);
272                 free(prop);
273                 return -1;
274             }
275             strcpy(prop->value, sep + 1);
276             
277             if(strstr(p, "password")){
278                 TRACE("hiding password...");
279                 memset(sep + 1, ' ', strlen(sep + 1));
280             }
281         }else{
282             TRACE("flag");
283
284             if(!(prop->value = malloc(2))){
285                 WARN("out of mem!");
286                 free(prop->key);
287                 free(prop);
288                 return -1;
289             }
290             strcpy(prop->value, "");
291             
292         }
293
294         list_add(&prop->list, &class->properties);
295
296     }
297
298     return 0;
299 }
300
301