An error occurred while loading the file. Please try again.
-
Simon Morlat authored999d216d
/***************************************************************************
* lpconfig.c
*
* Thu Mar 10 11:13:44 2005
* Copyright 2005 Simon Morlat
* Email simon.morlat@linphone.org
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define MAX_LEN 1024
#include "linphonecore.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#if !defined(_WIN32_WCE)
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif /*_WIN32_WCE*/
#define lp_new0(type,n) (type*)calloc(sizeof(type),n)
#include "lpconfig.h"
typedef struct _LpItem{
char *key;
char *value;
} LpItem;
typedef struct _LpSection{
char *name;
MSList *items;
} LpSection;
struct _LpConfig{
FILE *file;
char *filename;
MSList *sections;
int modified;
int readonly;
};
LpItem * lp_item_new(const char *key, const char *value){
LpItem *item=lp_new0(LpItem,1);
item->key=ortp_strdup(key);
item->value=ortp_strdup(value);
return item;
}
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
LpSection *lp_section_new(const char *name){
LpSection *sec=lp_new0(LpSection,1);
sec->name=ortp_strdup(name);
return sec;
}
void lp_item_destroy(void *pitem){
LpItem *item=(LpItem*)pitem;
free(item->key);
free(item->value);
free(item);
}
void lp_section_destroy(LpSection *sec){
free(sec->name);
ms_list_for_each(sec->items,lp_item_destroy);
ms_list_free(sec->items);
free(sec);
}
void lp_section_add_item(LpSection *sec,LpItem *item){
sec->items=ms_list_append(sec->items,(void *)item);
}
void lp_config_add_section(LpConfig *lpconfig, LpSection *section){
lpconfig->sections=ms_list_append(lpconfig->sections,(void *)section);
}
void lp_config_remove_section(LpConfig *lpconfig, LpSection *section){
lpconfig->sections=ms_list_remove(lpconfig->sections,(void *)section);
lp_section_destroy(section);
}
static bool_t is_first_char(const char *start, const char *pos){
const char *p;
for(p=start;p<pos;p++){
if (*p!=' ') return FALSE;
}
return TRUE;
}
LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){
LpSection *sec;
MSList *elem;
/*printf("Looking for section %s\n",name);*/
for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){
sec=(LpSection*)elem->data;
if (strcmp(sec->name,name)==0){
/*printf("Section %s found\n",name);*/
return sec;
}
}
return NULL;
}
LpItem *lp_section_find_item(LpSection *sec, const char *name){
MSList *elem;
LpItem *item;
/*printf("Looking for item %s\n",name);*/
for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){
item=(LpItem*)elem->data;
if (strcmp(item->key,name)==0) {
/*printf("Item %s found\n",name);*/
return item;
}
}
return NULL;
}
void lp_config_parse(LpConfig *lpconfig, FILE *file){
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
char tmp[MAX_LEN];
LpSection *cur=NULL;
if (file==NULL) return;
while(fgets(tmp,MAX_LEN,file)!=NULL){
char *pos1,*pos2;
pos1=strchr(tmp,'[');
if (pos1!=NULL && is_first_char(tmp,pos1) ){
pos2=strchr(pos1,']');
if (pos2!=NULL){
int nbs;
char secname[MAX_LEN];
secname[0]='\0';
/* found section */
*pos2='\0';
nbs = sscanf(pos1+1,"%s",secname);
if (nbs == 1 ){
if (strlen(secname)>0){
cur=lp_config_find_section (lpconfig,secname);
if (cur==NULL){
cur=lp_section_new(secname);
lp_config_add_section(lpconfig,cur);
}
}
}else{
ms_warning("parse error!");
}
}
}else {
pos1=strchr(tmp,'=');
if (pos1!=NULL){
char key[MAX_LEN];
key[0]='\0';
*pos1='\0';
if (sscanf(tmp,"%s",key)>0){
pos1++;
pos2=strchr(pos1,'\n');
if (pos2==NULL) pos2=pos1+strlen(pos1);
else {
*pos2='\0'; /*replace the '\n' */
pos2--;
}
/* remove ending white spaces */
for (; pos2>pos1 && *pos2==' ';pos2--) *pos2='\0';
if (pos2-pos1>=0){
/* found a pair key,value */
if (cur!=NULL){
LpItem *item=lp_section_find_item(cur,key);
if (item==NULL){
lp_section_add_item(cur,lp_item_new(key,pos1));
}else{
ms_free(item->value);
item->value=strdup(pos1);
}
/*printf("Found %s %s=%s\n",cur->name,key,pos1);*/
}else{
ms_warning("found key,item but no sections");
}
}
}
}
}
}
}
LpConfig * lp_config_new(const char *filename){
LpConfig *lpconfig=lp_new0(LpConfig,1);
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
if (filename!=NULL){
lpconfig->filename=ortp_strdup(filename);
lpconfig->file=fopen(filename,"rw");
if (lpconfig->file!=NULL){
lp_config_parse(lpconfig,lpconfig->file);
fclose(lpconfig->file);
#if !defined(_WIN32_WCE)
/* make existing configuration files non-group/world-accessible */
if (chmod(filename, S_IRUSR | S_IWUSR) == -1)
ms_warning("unable to correct permissions on "
"configuration file: %s",
strerror(errno));
#endif /*_WIN32_WCE*/
lpconfig->file=NULL;
lpconfig->modified=0;
}
}
return lpconfig;
}
int lp_config_read_file(LpConfig *lpconfig, const char *filename){
FILE* f=fopen(filename,"r");
if (f!=NULL){
lp_config_parse(lpconfig,f);
fclose(f);
return 0;
}
ms_warning("Fail to open file %s",filename);
return -1;
}
void lp_item_set_value(LpItem *item, const char *value){
free(item->value);
item->value=ortp_strdup(value);
}
void lp_config_destroy(LpConfig *lpconfig){
if (lpconfig->filename!=NULL) free(lpconfig->filename);
ms_list_for_each(lpconfig->sections,(void (*)(void*))lp_section_destroy);
ms_list_free(lpconfig->sections);
free(lpconfig);
}
void lp_section_remove_item(LpSection *sec, LpItem *item){
sec->items=ms_list_remove(sec->items,(void *)item);
lp_item_destroy(item);
}
const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string){
LpSection *sec;
LpItem *item;
sec=lp_config_find_section(lpconfig,section);
if (sec!=NULL){
item=lp_section_find_item(sec,key);
if (item!=NULL) return item->value;
}
return default_string;
}
int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value){
const char *str=lp_config_get_string(lpconfig,section,key,NULL);
if (str!=NULL) return atoi(str);
else return default_value;
}
float lp_config_get_float(LpConfig *lpconfig,const char *section, const char *key, float default_value){
const char *str=lp_config_get_string(lpconfig,section,key,NULL);
float ret=default_value;
if (str==NULL) return default_value;
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
sscanf(str,"%f",&ret);
return ret;
}
void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){
LpItem *item;
LpSection *sec=lp_config_find_section(lpconfig,section);
if (sec!=NULL){
item=lp_section_find_item(sec,key);
if (item!=NULL){
if (value!=NULL)
lp_item_set_value(item,value);
else lp_section_remove_item(sec,item);
}else{
if (value!=NULL)
lp_section_add_item(sec,lp_item_new(key,value));
}
}else if (value!=NULL){
sec=lp_section_new(section);
lp_config_add_section(lpconfig,sec);
lp_section_add_item(sec,lp_item_new(key,value));
}
lpconfig->modified++;
}
void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){
char tmp[30];
snprintf(tmp,30,"%i",value);
lp_config_set_string(lpconfig,section,key,tmp);
lpconfig->modified++;
}
void lp_item_write(LpItem *item, FILE *file){
fprintf(file,"%s=%s\n",item->key,item->value);
}
void lp_section_write(LpSection *sec, FILE *file){
fprintf(file,"[%s]\n",sec->name);
ms_list_for_each2(sec->items,(void (*)(void*, void*))lp_item_write,(void *)file);
fprintf(file,"\n");
}
int lp_config_sync(LpConfig *lpconfig){
FILE *file;
if (lpconfig->filename==NULL) return -1;
if (lpconfig->readonly) return 0;
#ifndef WIN32
/* don't create group/world-accessible files */
(void) umask(S_IRWXG | S_IRWXO);
#endif
file=fopen(lpconfig->filename,"w");
if (file==NULL){
ms_warning("Could not write %s ! Maybe it is read-only. Configuration will not be saved.",lpconfig->filename);
lpconfig->readonly=1;
return -1;
}
ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file);
fclose(file);
lpconfig->modified=0;
return 0;
}
int lp_config_has_section(LpConfig *lpconfig, const char *section){
if (lp_config_find_section(lpconfig,section)!=NULL) return 1;
return 0;
}
void lp_config_clean_section(LpConfig *lpconfig, const char *section){
LpSection *sec=lp_config_find_section(lpconfig,section);
if (sec!=NULL){
351352353354355356357358359
lp_config_remove_section(lpconfig,sec);
}
lpconfig->modified++;
}
int lp_config_needs_commit(const LpConfig *lpconfig){
return lpconfig->modified>0;
}