mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-01 18:21:31 -04:00
More fixes for new config system
This commit is contained in:
parent
87f84ded09
commit
1d0a3c4149
135
src/conf.c
135
src/conf.c
@ -26,10 +26,11 @@
|
|||||||
* Config file reading and writing
|
* Config file reading and writing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_conf_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -40,9 +41,10 @@
|
|||||||
|
|
||||||
/** Globals */
|
/** Globals */
|
||||||
static int ecode;
|
static int ecode;
|
||||||
static LL_HANDLE config_main=NULL;
|
static LL_HANDLE conf_main=NULL;
|
||||||
|
static pthread_mutex_t conf_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
#define CONFIG_LINEBUFFER 128
|
#define conf_LINEBUFFER 128
|
||||||
|
|
||||||
#define CONF_T_INT 0
|
#define CONF_T_INT 0
|
||||||
#define CONF_T_STRING 1
|
#define CONF_T_STRING 1
|
||||||
@ -51,7 +53,8 @@ static LL_HANDLE config_main=NULL;
|
|||||||
static int _conf_verify(LL_HANDLE pll);
|
static int _conf_verify(LL_HANDLE pll);
|
||||||
static LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term);
|
static LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term);
|
||||||
static int _conf_exists(LL_HANDLE pll, char *section, char *term);
|
static int _conf_exists(LL_HANDLE pll, char *section, char *term);
|
||||||
|
static void _conf_lock(void);
|
||||||
|
static void _conf_unlock(void);
|
||||||
|
|
||||||
|
|
||||||
typedef struct _CONF_ELEMENTS {
|
typedef struct _CONF_ELEMENTS {
|
||||||
@ -90,6 +93,30 @@ static CONF_ELEMENTS conf_elements[] = {
|
|||||||
{ 0, 0, CONF_T_INT, NULL, NULL }
|
{ 0, 0, CONF_T_INT, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lock the conf mutex
|
||||||
|
*/
|
||||||
|
void _conf_lock() {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if((err=pthread_mutex_lock(&conf_mutex))) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"Cannot lock configuration mutex: %s\n",
|
||||||
|
strerror(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unlock the conf mutex
|
||||||
|
*/
|
||||||
|
void _conf_unlock() {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if((err = pthread_mutex_unlock(&conf_mutex))) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"Cannot unlock configuration mutex %s\n",
|
||||||
|
strerror(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch item based on section/term basis, rather than just a single
|
* fetch item based on section/term basis, rather than just a single
|
||||||
* level deep, like ll_fetch_item does
|
* level deep, like ll_fetch_item does
|
||||||
@ -104,13 +131,13 @@ LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term) {
|
|||||||
LL_ITEM *pitem;
|
LL_ITEM *pitem;
|
||||||
|
|
||||||
if(!(psection = ll_fetch_item(pll,section)))
|
if(!(psection = ll_fetch_item(pll,section)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(psection->type != LL_TYPE_LL)
|
if(psection->type != LL_TYPE_LL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(!(pitem = ll_fetch_item(psection->value.as_ll,term)))
|
if(!(pitem = ll_fetch_item(psection->value.as_ll,term)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return pitem;
|
return pitem;
|
||||||
}
|
}
|
||||||
@ -125,7 +152,7 @@ LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term) {
|
|||||||
*/
|
*/
|
||||||
int _conf_exists(LL_HANDLE pll, char *section, char *term) {
|
int _conf_exists(LL_HANDLE pll, char *section, char *term) {
|
||||||
if(!_conf_fetch_item(pll,section,term))
|
if(!_conf_fetch_item(pll,section,term))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -149,11 +176,12 @@ int _conf_verify(LL_HANDLE pll) {
|
|||||||
pce = &conf_elements[0];
|
pce = &conf_elements[0];
|
||||||
while(pce->section) {
|
while(pce->section) {
|
||||||
if(pce->required) {
|
if(pce->required) {
|
||||||
if(!_conf_exists(pll,pce->section, pce->term))
|
if(!_conf_exists(pll,pce->section, pce->term)) {
|
||||||
DPRINTF(E_LOG,L_CONF,"Missing configuration entry "
|
DPRINTF(E_LOG,L_CONF,"Missing configuration entry "
|
||||||
" %s/%s. Please review the sample config\n",
|
" %s/%s. Please review the sample config\n",
|
||||||
pce->section, pce->term);
|
pce->section, pce->term);
|
||||||
is_valid=FALSE;
|
is_valid=FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(pce->deprecated) {
|
if(pce->deprecated) {
|
||||||
DPRINTF(E_LOG,L_CONF,"Config entry %s/%s is deprecated. Please "
|
DPRINTF(E_LOG,L_CONF,"Config entry %s/%s is deprecated. Please "
|
||||||
@ -176,11 +204,11 @@ int _conf_verify(LL_HANDLE pll) {
|
|||||||
* @param file file to read
|
* @param file file to read
|
||||||
* @returns TRUE if successful, FALSE otherwise
|
* @returns TRUE if successful, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
int config_read(char *file) {
|
int conf_read(char *file) {
|
||||||
FILE *fin;
|
FILE *fin;
|
||||||
int err;
|
int err;
|
||||||
LL_HANDLE pllnew, plltemp, pllcurrent;
|
LL_HANDLE pllnew, plltemp, pllcurrent;
|
||||||
char linebuffer[CONFIG_LINEBUFFER+1];
|
char linebuffer[conf_LINEBUFFER+1];
|
||||||
char *comment, *term, *value, *delim;
|
char *comment, *term, *value, *delim;
|
||||||
int compat_mode=1;
|
int compat_mode=1;
|
||||||
int line=0;
|
int line=0;
|
||||||
@ -201,9 +229,9 @@ int config_read(char *file) {
|
|||||||
/* got what will be the root of the config tree, now start walking through
|
/* got what will be the root of the config tree, now start walking through
|
||||||
* the input file, populating the tree
|
* the input file, populating the tree
|
||||||
*/
|
*/
|
||||||
while(fgets(linebuffer,CONFIG_LINEBUFFER,fin)) {
|
while(fgets(linebuffer,conf_LINEBUFFER,fin)) {
|
||||||
line++;
|
line++;
|
||||||
linebuffer[CONFIG_LINEBUFFER] = '\0';
|
linebuffer[conf_LINEBUFFER] = '\0';
|
||||||
|
|
||||||
comment=strchr(linebuffer,'#');
|
comment=strchr(linebuffer,'#');
|
||||||
if(comment) {
|
if(comment) {
|
||||||
@ -278,10 +306,18 @@ int config_read(char *file) {
|
|||||||
fclose(fin);
|
fclose(fin);
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
_conf_verify(pllnew);
|
if(_conf_verify(pllnew)) {
|
||||||
|
DPRINTF(E_INF,L_CONF,"Loading new config file.\n");
|
||||||
ll_dump(pllnew);
|
_conf_lock();
|
||||||
ll_destroy(pllnew);
|
if(conf_main) {
|
||||||
|
ll_destroy(conf_main);
|
||||||
|
}
|
||||||
|
conf_main = pllnew;
|
||||||
|
_conf_unlock();
|
||||||
|
} else {
|
||||||
|
ll_destroy(pllnew);
|
||||||
|
DPRINTF(E_LOG,L_CONF,"Could not validate config file. Ignoring\n");
|
||||||
|
}
|
||||||
|
|
||||||
return CONF_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -289,9 +325,9 @@ int config_read(char *file) {
|
|||||||
/**
|
/**
|
||||||
* do final config file shutdown
|
* do final config file shutdown
|
||||||
*/
|
*/
|
||||||
int config_close(void) {
|
int conf_close(void) {
|
||||||
if(config_main)
|
if(conf_main)
|
||||||
ll_destroy(config_main);
|
ll_destroy(conf_main);
|
||||||
|
|
||||||
return CONF_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -302,11 +338,60 @@ int config_close(void) {
|
|||||||
*
|
*
|
||||||
* @param section section name to search in
|
* @param section section name to search in
|
||||||
* @param key key to search for
|
* @param key key to search for
|
||||||
* @param default default value to return if key not found
|
* @param dflt default value to return if key not found
|
||||||
* @returns value as integer if found, default value otherwise
|
* @returns value as integer if found, dflt value otherwise
|
||||||
*/
|
*/
|
||||||
int config_get_int(char *section, char *key, int default) {
|
int conf_get_int(char *section, char *key, int dflt) {
|
||||||
LL_ITEM *pitem;
|
LL_ITEM *pitem;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
_conf_lock();
|
||||||
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
|
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
||||||
|
retval = dflt;
|
||||||
|
} else {
|
||||||
|
retval = atoi(pitem->value.as_string);
|
||||||
|
}
|
||||||
|
_conf_unlock();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read a value from the CURRENT config tree as a string
|
||||||
|
*
|
||||||
|
* @param section section name to search in
|
||||||
|
* @param key key to search for
|
||||||
|
* @param dflt default value to return if key not found
|
||||||
|
* @param out buffer to put resulting string in
|
||||||
|
* @param size pointer to size of buffer
|
||||||
|
* @returns CONF_E_SUCCESS with out filled on success,
|
||||||
|
* or CONF_E_OVERFLOW, with size set to required buffer size
|
||||||
|
*/
|
||||||
|
int conf_get_string(char *section, char *key, char *dflt, char *out, int *size) {
|
||||||
|
LL_ITEM *pitem;
|
||||||
|
char *result;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
_conf_lock();
|
||||||
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
|
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
||||||
|
result = dflt;
|
||||||
|
} else {
|
||||||
|
result = pitem->value.as_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(result) + 1;
|
||||||
|
|
||||||
|
if(len <= *size) {
|
||||||
|
*size = len;
|
||||||
|
strcpy(out,result);
|
||||||
|
} else {
|
||||||
|
_conf_unlock();
|
||||||
|
*size = len;
|
||||||
|
return CONF_E_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
_conf_unlock();
|
||||||
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
12
src/conf.h
12
src/conf.h
@ -27,12 +27,14 @@
|
|||||||
#define CONF_E_UNKNOWN 2
|
#define CONF_E_UNKNOWN 2
|
||||||
#define CONF_E_BADHEADER 3
|
#define CONF_E_BADHEADER 3
|
||||||
#define CONF_E_PARSE 4
|
#define CONF_E_PARSE 4
|
||||||
|
#define CONF_E_OVERFLOW 5 /** <Buffer passed too small */
|
||||||
|
|
||||||
|
|
||||||
extern int config_read(char *file);
|
|
||||||
extern int config_close(void);
|
extern int conf_read(char *file);
|
||||||
extern int config_get_int(char *section, char *key, int default);
|
extern int conf_close(void);
|
||||||
extern int config_get_string(char *section, char *key, char *default,
|
extern int conf_get_int(char *section, char *key, int dflt);
|
||||||
char *out, int size);
|
extern int conf_get_string(char *section, char *key, char *dflt,
|
||||||
|
char *out, int *size);
|
||||||
|
|
||||||
#endif /* _CONFIG_H_ */
|
#endif /* _CONFIG_H_ */
|
||||||
|
@ -14,10 +14,10 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
printf("Reading %s\n",argv[1]);
|
printf("Reading %s\n",argv[1]);
|
||||||
|
|
||||||
if((err=config_read(argv[1])) != CONF_E_SUCCESS) {
|
if((err=conf_read(argv[1])) != CONF_E_SUCCESS) {
|
||||||
printf("Error reading config: %d\n",err);
|
printf("Error reading config: %d\n",err);
|
||||||
} else {
|
} else {
|
||||||
printf("Read config!\n");
|
printf("Read config!\n");
|
||||||
}
|
}
|
||||||
config_close();
|
conf_close();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user