source: mediastreamer2/linphone/coreapi/lpconfig.c @ 0:5a6e836a86a3

Last change on this file since 0:5a6e836a86a3 was 0:5a6e836a86a3, checked in by aymeric <aymeric@…>, 5 years ago

Initial import

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@1 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File size: 9.0 KB
Line 
1/***************************************************************************
2 *            lpconfig.c
3 *
4 *  Thu Mar 10 11:13:44 2005
5 *  Copyright  2005  Simon Morlat
6 *  Email simon.morlat@linphone.org
7 ****************************************************************************/
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 Library General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this program; if not, write to the Free Software
22 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25#define MAX_LEN 1024
26
27#include "linphonecore.h"
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33#include <errno.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36
37#define lp_new0(type,n) (type*)calloc(sizeof(type),n)
38
39#include "lpconfig.h"
40
41#define LISTNODE(_struct_)      \
42        struct _struct_ *_prev;\
43        struct _struct_ *_next;
44
45typedef struct _ListNode{
46        LISTNODE(_ListNode)
47} ListNode;
48
49typedef void (*ListNodeForEachFunc)(ListNode *);
50
51ListNode * list_node_append(ListNode *head,ListNode *elem){
52        ListNode *e=head;
53        while(e->_next!=NULL) e=e->_next;
54        e->_next=elem;
55        elem->_prev=e;
56        return head;
57}
58
59ListNode * list_node_remove(ListNode *head, ListNode *elem){
60        ListNode *before,*after;
61        before=elem->_prev;
62        after=elem->_next;
63        if (before!=NULL) before->_next=after;
64        if (after!=NULL) after->_prev=before;
65        elem->_prev=NULL;
66        elem->_next=NULL;
67        if (head==elem) return after;
68        return head;
69}
70
71void list_node_foreach(ListNode *head, ListNodeForEachFunc func){
72        for (;head!=NULL;head=head->_next){
73                func(head);
74        }
75}
76
77
78#define LIST_PREPEND(e1,e2) (  (e2)->_prev=NULL,(e2)->_next=(e1),(e1)->_prev=(e2),(e2) )
79#define LIST_APPEND(head,elem) ((head)==0 ? (elem) : (list_node_append((ListNode*)(head),(ListNode*)(elem)), (head)) )
80#define LIST_REMOVE(head,elem)
81
82/* returns void */
83#define LIST_FOREACH(head) list_node_foreach((ListNode*)head)
84
85typedef struct _LpItem{
86        char *key;
87        char *value;
88} LpItem;
89
90typedef struct _LpSection{
91        char *name;
92        MSList *items;
93} LpSection;
94
95struct _LpConfig{
96        FILE *file;
97        char *filename;
98        MSList *sections;
99};
100
101LpItem * lp_item_new(const char *key, const char *value){
102        LpItem *item=lp_new0(LpItem,1);
103        item->key=strdup(key);
104        item->value=strdup(value);
105        return item;
106}
107
108LpSection *lp_section_new(const char *name){
109        LpSection *sec=lp_new0(LpSection,1);
110        sec->name=strdup(name);
111        return sec;
112}
113
114void lp_item_destroy(void *pitem){
115        LpItem *item=(LpItem*)pitem;
116        free(item->key);
117        free(item->value);
118        free(item);
119}
120
121void lp_section_destroy(LpSection *sec){
122        free(sec->name);
123        ms_list_for_each(sec->items,lp_item_destroy);
124        ms_list_free(sec->items);
125        free(sec);
126}
127
128void lp_section_add_item(LpSection *sec,LpItem *item){
129        sec->items=ms_list_append(sec->items,(void *)item);
130}
131
132void lp_config_add_section(LpConfig *lpconfig, LpSection *section){
133        lpconfig->sections=ms_list_append(lpconfig->sections,(void *)section);
134}
135
136void lp_config_remove_section(LpConfig *lpconfig, LpSection *section){
137        lpconfig->sections=ms_list_remove(lpconfig->sections,(void *)section);
138        lp_section_destroy(section);
139}
140
141static bool_t is_first_char(const char *start, const char *pos){
142        const char *p;
143        for(p=start;p<pos;p++){
144                if (*p!=' ') return FALSE;
145        }
146        return TRUE;
147}
148
149void lp_config_parse(LpConfig *lpconfig){
150        char tmp[MAX_LEN];
151        LpSection *cur=NULL;
152       
153        if (lpconfig->file==NULL) return;
154       
155        while(fgets(tmp,MAX_LEN,lpconfig->file)!=NULL){
156                char *pos1,*pos2;
157                pos1=strchr(tmp,'[');
158                if (pos1!=NULL && is_first_char(tmp,pos1) ){
159                        pos2=strchr(pos1,']');
160                        if (pos2!=NULL){
161                                int nbs;
162                                char secname[MAX_LEN];
163                                secname[0]='\0';
164                                /* found section */
165                                *pos2='\0';
166                                nbs = sscanf(pos1+1,"%s",secname);
167                                if (nbs == 1 ){
168                                        if (strlen(secname)>0){
169                                                cur=lp_section_new(secname);
170                                                lp_config_add_section(lpconfig,cur);
171                                        }
172                                }else{
173                                        ms_warning("parse error!");
174                                }
175                        }
176                }else {
177                        pos1=strchr(tmp,'=');
178                        if (pos1!=NULL){
179                                char key[MAX_LEN];
180                                key[0]='\0';
181                               
182                                *pos1='\0';
183                                if (sscanf(tmp,"%s",key)>0){
184                                       
185                                        pos1++;
186                                        pos2=strchr(pos1,'\n');
187                                        if (pos2==NULL) pos2=pos1+strlen(pos2);
188                                        else {
189                                                *pos2='\0'; /*replace the '\n' */
190                                                pos2--;
191                                        }
192                                        /* remove ending white spaces */
193                                        for (; pos2>pos1 && *pos2==' ';pos2--) *pos2='\0';
194                                        if (pos2-pos1>=0){
195                                                /* found a pair key,value */
196                                                if (cur!=NULL){
197                                                        lp_section_add_item(cur,lp_item_new(key,pos1));
198                                                        /*printf("Found %s %s=%s\n",cur->name,key,pos1);*/
199                                                }else{
200                                                        ms_warning("found key,item but no sections");
201                                                }
202                                        }
203                                }
204                        }
205                }
206        }
207}
208
209LpConfig * lp_config_new(const char *filename){
210        LpConfig *lpconfig=lp_new0(LpConfig,1);
211        if (filename!=NULL){
212                lpconfig->filename=strdup(filename);
213                lpconfig->file=fopen(filename,"rw");
214                if (lpconfig->file!=NULL){
215                        lp_config_parse(lpconfig);
216                        fclose(lpconfig->file);
217                        /* make existing configuration files non-group/world-accessible */
218                        if (chmod(filename, S_IRUSR | S_IWUSR) == -1)
219                                ms_warning("unable to correct permissions on "
220                                          "configuration file: %s",
221                                           strerror(errno));
222                        lpconfig->file=NULL;
223                }
224        }
225        return lpconfig;
226}
227
228void lp_item_set_value(LpItem *item, const char *value){
229        free(item->value);
230        item->value=strdup(value);
231}
232
233
234void lp_config_destroy(LpConfig *lpconfig){
235        if (lpconfig->filename!=NULL) free(lpconfig->filename);
236        ms_list_for_each(lpconfig->sections,(void (*)(void*))lp_section_destroy);
237        ms_list_free(lpconfig->sections);
238        free(lpconfig);
239}
240
241LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){
242        LpSection *sec;
243        MSList *elem;
244        /*printf("Looking for section %s\n",name);*/
245        for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){
246                sec=(LpSection*)elem->data;
247                if (strcmp(sec->name,name)==0){
248                        /*printf("Section %s found\n",name);*/
249                        return sec;
250                }
251        }
252        return NULL;
253}
254
255LpItem *lp_section_find_item(LpSection *sec, const char *name){
256        MSList *elem;
257        LpItem *item;
258        /*printf("Looking for item %s\n",name);*/
259        for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){
260                item=(LpItem*)elem->data;
261                if (strcmp(item->key,name)==0) {
262                        /*printf("Item %s found\n",name);*/
263                        return item;
264                }
265        }
266        return NULL;
267}
268
269void lp_section_remove_item(LpSection *sec, LpItem *item){
270        sec->items=ms_list_remove(sec->items,(void *)item);
271        lp_item_destroy(item);
272}
273
274const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string){
275        LpSection *sec;
276        LpItem *item;
277        sec=lp_config_find_section(lpconfig,section);
278        if (sec!=NULL){
279                item=lp_section_find_item(sec,key);
280                if (item!=NULL) return item->value;
281        }
282        return default_string;
283}
284
285int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value){
286        const char *str=lp_config_get_string(lpconfig,section,key,NULL);
287        if (str!=NULL) return atoi(str);
288        else return default_value;
289}
290
291void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){
292        LpItem *item;
293        LpSection *sec=lp_config_find_section(lpconfig,section);
294        if (sec!=NULL){
295                item=lp_section_find_item(sec,key);
296                if (item!=NULL){
297                        if (value!=NULL)
298                                lp_item_set_value(item,value);
299                        else lp_section_remove_item(sec,item);
300                }else{
301                        if (value!=NULL)
302                                lp_section_add_item(sec,lp_item_new(key,value));
303                }
304        }else if (value!=NULL){
305                sec=lp_section_new(section);
306                lp_config_add_section(lpconfig,sec);
307                lp_section_add_item(sec,lp_item_new(key,value));
308        }
309}
310
311void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){
312        char tmp[30];
313        snprintf(tmp,30,"%i",value);
314        lp_config_set_string(lpconfig,section,key,tmp);
315}
316
317void lp_item_write(LpItem *item, FILE *file){
318        fprintf(file,"%s=%s\n",item->key,item->value);
319}
320
321void lp_section_write(LpSection *sec, FILE *file){
322        fprintf(file,"[%s]\n",sec->name);
323        ms_list_for_each2(sec->items,(void (*)(void*, void*))lp_item_write,(void *)file);
324        fprintf(file,"\n");
325}
326
327int lp_config_sync(LpConfig *lpconfig){
328        FILE *file;
329        if (lpconfig->filename==NULL) return -1;
330#ifndef WIN32
331        /* don't create group/world-accessible files */
332        (void) umask(S_IRWXG | S_IRWXO);
333#endif
334        file=fopen(lpconfig->filename,"w");
335        if (file==NULL){
336                ms_warning("Could not write %s !",lpconfig->filename);
337                return -1;
338        }
339        ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file);
340        fclose(file);
341        return 0;
342}
343
344int lp_config_has_section(LpConfig *lpconfig, const char *section){
345        if (lp_config_find_section(lpconfig,section)!=NULL) return 1;
346        return 0;
347}
348
349void lp_config_clean_section(LpConfig *lpconfig, const char *section){
350        LpSection *sec=lp_config_find_section(lpconfig,section);
351        if (sec!=NULL){
352                lp_config_remove_section(lpconfig,sec);
353        }
354}
Note: See TracBrowser for help on using the repository browser.