mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-15 16:48:22 -04:00
More incremental config changes
This commit is contained in:
parent
49e9b3be32
commit
3d27be7405
@ -32,18 +32,75 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "ll.h"
|
#include "ll.h"
|
||||||
#include "daapd.h"
|
#include "daapd.h"
|
||||||
|
|
||||||
/** Globals */
|
/** Globals */
|
||||||
int ecode;
|
static int ecode;
|
||||||
LL_HANDLE config_main=NULL;
|
static LL_HANDLE config_main=NULL;
|
||||||
|
|
||||||
#define CONFIG_LINEBUFFER 128
|
#define CONFIG_LINEBUFFER 128
|
||||||
|
|
||||||
|
#define CONF_T_INT 0
|
||||||
|
#define CONF_T_STRING 1
|
||||||
|
|
||||||
|
/** Forwards */
|
||||||
|
static int _ll_verify(LL_HANDLE pll);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _CONF_ELEMENTS {
|
||||||
|
int required;
|
||||||
|
int deprecated;
|
||||||
|
int type;
|
||||||
|
char *section;
|
||||||
|
char *term;
|
||||||
|
} CONF_ELEMENTS;
|
||||||
|
|
||||||
|
static CONF_ELEMENTS conf_elements[] = {
|
||||||
|
{ 1, 0, CONF_T_STRING,"general","runas" },
|
||||||
|
{ 1, 0, CONF_T_STRING,"general","web_root" },
|
||||||
|
{ 1, 0, CONF_T_INT,"general","port" },
|
||||||
|
{ 1, 0, CONF_T_STRING,"general","admin_pw" },
|
||||||
|
{ 1, 0, CONF_T_STRING,"general","mp3_dir" },
|
||||||
|
{ 0, 1, CONF_T_STRING,"general","db_dir" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","db_type" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","db_parms" },
|
||||||
|
{ 0, 0, CONF_T_INT,"general","debuglevel" },
|
||||||
|
{ 1, 0, CONF_T_STRING,"general","servername" },
|
||||||
|
{ 0, 0, CONF_T_INT,"general","rescan_interval" },
|
||||||
|
{ 0, 0, CONF_T_INT,"general","always_scan" },
|
||||||
|
{ 0, 1, CONF_T_INT,"general","latin1_tags" },
|
||||||
|
{ 0, 0, CONF_T_INT,"general","process_m3u" },
|
||||||
|
{ 0, 0, CONF_T_INT,"general","scan_type" },
|
||||||
|
{ 0, 1, CONF_T_INT,"general","compress" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","playlist" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","extensions" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","interface" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","ssc_codectypes" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","ssc_prog" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","password" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","compdirs" },
|
||||||
|
{ 0, 0, CONF_T_STRING,"general","logfile" }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read a configfile into a bag
|
* check a tree and make sure it doesn't have any obviously bad
|
||||||
|
* configuration information
|
||||||
|
*
|
||||||
|
* @param pll tree to check
|
||||||
|
*/
|
||||||
|
int _ll_verify(LL_HANDLE pll) {
|
||||||
|
|
||||||
|
|
||||||
|
return LL_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read a configfile into a tree
|
||||||
*
|
*
|
||||||
* @param file file to read
|
* @param file file to read
|
||||||
* @returns TRUE if successful, FALSE otherwise
|
* @returns TRUE if successful, FALSE otherwise
|
||||||
@ -51,26 +108,30 @@ LL_HANDLE config_main=NULL;
|
|||||||
int config_read(char *file) {
|
int config_read(char *file) {
|
||||||
FILE *fin;
|
FILE *fin;
|
||||||
int err;
|
int err;
|
||||||
LL_HANDLE pllnew, plltemp;
|
LL_HANDLE pllnew, plltemp, pllcurrent;
|
||||||
char linebuffer[CONFIG_LINEBUFFER+1];
|
char linebuffer[CONFIG_LINEBUFFER+1];
|
||||||
char *comment, *term, *value, *delim;
|
char *comment, *term, *value, *delim;
|
||||||
int compat_mode=1;
|
int compat_mode=1;
|
||||||
|
int line=0;
|
||||||
|
|
||||||
fin=fopen(file,"r");
|
fin=fopen(file,"r");
|
||||||
if(!fin) {
|
if(!fin) {
|
||||||
return CONFIG_E_FOPEN;
|
return CONF_E_FOPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((err=ll_create(&pllnew)) != LL_E_SUCCESS) {
|
if((err=ll_create(&pllnew)) != LL_E_SUCCESS) {
|
||||||
DPRINTF(E_LOG,L_CONF,"Error creating linked list: %d\n",err);
|
DPRINTF(E_LOG,L_CONF,"Error creating linked list: %d\n",err);
|
||||||
fclose(fin);
|
fclose(fin);
|
||||||
return CONFIG_E_UNKNOWN;
|
return CONF_E_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pllcurrent=NULL;
|
||||||
|
|
||||||
/* 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,CONFIG_LINEBUFFER,fin)) {
|
||||||
|
line++;
|
||||||
linebuffer[CONFIG_LINEBUFFER] = '\0';
|
linebuffer[CONFIG_LINEBUFFER] = '\0';
|
||||||
|
|
||||||
comment=strchr(linebuffer,'#');
|
comment=strchr(linebuffer,'#');
|
||||||
@ -90,17 +151,18 @@ int config_read(char *file) {
|
|||||||
if(!value) {
|
if(!value) {
|
||||||
ll_destroy(pllnew);
|
ll_destroy(pllnew);
|
||||||
fclose(fin);
|
fclose(fin);
|
||||||
return CONFIG_E_BADHEADER;
|
return CONF_E_BADHEADER;
|
||||||
}
|
}
|
||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
|
||||||
if((err = ll_create(&plltemp)) != LL_E_SUCCESS) {
|
if((err = ll_create(&plltemp)) != LL_E_SUCCESS) {
|
||||||
ll_destroy(pllnew);
|
ll_destroy(pllnew);
|
||||||
fclose(fin);
|
fclose(fin);
|
||||||
return CONFIG_E_UNKNOWN;
|
return CONF_E_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ll_add_ll(pllnew,term,plltemp);
|
ll_add_ll(pllnew,term,plltemp);
|
||||||
|
pllcurrent = plltemp;
|
||||||
} else {
|
} else {
|
||||||
/* k/v pair */
|
/* k/v pair */
|
||||||
term=&linebuffer[0];
|
term=&linebuffer[0];
|
||||||
@ -121,7 +183,23 @@ int config_read(char *file) {
|
|||||||
while(strlen(value) && (strchr("\t ",*value)))
|
while(strlen(value) && (strchr("\t ",*value)))
|
||||||
value++;
|
value++;
|
||||||
|
|
||||||
ll_add_string(pllnew,term,value);
|
if(!pllcurrent) {
|
||||||
|
/* we are definately in compat mode -- add a general section */
|
||||||
|
if((err=ll_create(&plltemp)) != LL_E_SUCCESS) {
|
||||||
|
DPRINTF(E_LOG,L_CONF,"Error creating linked list: %d\n",err);
|
||||||
|
ll_destroy(pllnew);
|
||||||
|
fclose(fin);
|
||||||
|
return CONF_E_UNKNOWN;
|
||||||
|
}
|
||||||
|
ll_add_ll(pllnew,"general",plltemp);
|
||||||
|
pllcurrent = plltemp;
|
||||||
|
}
|
||||||
|
ll_add_string(pllcurrent,term,value);
|
||||||
|
}
|
||||||
|
if(((term) && (strlen(term))) && (!value)) {
|
||||||
|
DPRINTF(E_LOG,L_CONF,"Error in config file on line %d\n",line);
|
||||||
|
ll_destroy(pllnew);
|
||||||
|
return CONF_E_PARSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,16 +207,18 @@ int config_read(char *file) {
|
|||||||
fclose(fin);
|
fclose(fin);
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
|
_ll_verify(pllnew);
|
||||||
|
|
||||||
ll_dump(pllnew);
|
ll_dump(pllnew);
|
||||||
ll_destroy(pllnew);
|
ll_destroy(pllnew);
|
||||||
|
|
||||||
return CONFIG_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_close(void) {
|
int config_close(void) {
|
||||||
if(config_main)
|
if(config_main)
|
||||||
ll_destroy(config_main);
|
ll_destroy(config_main);
|
||||||
|
|
||||||
return CONFIG_E_SUCCESS;
|
return CONF_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -22,10 +22,11 @@
|
|||||||
#ifndef _CONFIG_H_
|
#ifndef _CONFIG_H_
|
||||||
#define _CONFIG_H_
|
#define _CONFIG_H_
|
||||||
|
|
||||||
#define CONFIG_E_SUCCESS 0
|
#define CONF_E_SUCCESS 0
|
||||||
#define CONFIG_E_FOPEN 1
|
#define CONF_E_FOPEN 1
|
||||||
#define CONFIG_E_UNKNOWN 2
|
#define CONF_E_UNKNOWN 2
|
||||||
#define CONFIG_E_BADHEADER 3
|
#define CONF_E_BADHEADER 3
|
||||||
|
#define CONF_E_PARSE 4
|
||||||
|
|
||||||
|
|
||||||
extern int config_read(char *file);
|
extern int config_read(char *file);
|
@ -4,13 +4,20 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "conf.h"
|
||||||
|
#include "err.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if(config_read(argv[1]) != CONFIG_E_SUCCESS) {
|
int err;
|
||||||
printf("Read config!\n");
|
|
||||||
|
err_debuglevel = 9;
|
||||||
|
|
||||||
|
printf("Reading %s\n",argv[1]);
|
||||||
|
|
||||||
|
if((err=config_read(argv[1])) != CONF_E_SUCCESS) {
|
||||||
|
printf("Error reading config: %d\n",err);
|
||||||
} else {
|
} else {
|
||||||
printf("Error reading config\n");
|
printf("Read config!\n");
|
||||||
}
|
}
|
||||||
config_close();
|
config_close();
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS := $(CFLAGS) -g -DHAVE_CONFIG_H -I. -I..
|
CFLAGS := $(CFLAGS) -g -DHAVE_CONFIG_H -I. -I..
|
||||||
LDFLAGS := $(LDFLAGS)
|
LDFLAGS := $(LDFLAGS)
|
||||||
TARGET = config
|
TARGET = conf
|
||||||
OBJECTS=config-driver.o config.o ll.o
|
OBJECTS=config-driver.o conf.o ll.o err.o
|
||||||
|
|
||||||
$(TARGET): $(OBJECTS)
|
$(TARGET): $(OBJECTS)
|
||||||
$(CC) -o $(TARGET) $(LDFLAGS) $(OBJECTS)
|
$(CC) -o $(TARGET) $(LDFLAGS) $(OBJECTS)
|
||||||
|
64
src/ll.c
64
src/ll.c
@ -34,6 +34,7 @@
|
|||||||
/** Internal functions */
|
/** Internal functions */
|
||||||
|
|
||||||
int _ll_add_item(LL *pl, char *key, void *vpval, int ival, int type);
|
int _ll_add_item(LL *pl, char *key, void *vpval, int ival, int type);
|
||||||
|
void _ll_dump(LL *pl, int depth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a ll
|
* create a ll
|
||||||
@ -47,6 +48,9 @@ int ll_create(LL **ppl) {
|
|||||||
return LL_E_MALLOC;
|
return LL_E_MALLOC;
|
||||||
|
|
||||||
memset(*ppl,0x0,sizeof(struct _LL));
|
memset(*ppl,0x0,sizeof(struct _LL));
|
||||||
|
|
||||||
|
/* set default flags */
|
||||||
|
(*ppl)->flags = LL_FLAG_NODUPS | LL_FLAG_INHERIT;
|
||||||
return LL_E_SUCCESS;
|
return LL_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +92,7 @@ int ll_destroy(LL *pl) {
|
|||||||
* thin wrapper for _ll_add_item
|
* thin wrapper for _ll_add_item
|
||||||
*/
|
*/
|
||||||
int ll_add_string(LL *pl, char *key, char *cval) {
|
int ll_add_string(LL *pl, char *key, char *cval) {
|
||||||
return _ll_add_item(pl,cval,key,0,LL_TYPE_STRING);
|
return _ll_add_item(pl,key,cval,0,LL_TYPE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,7 +106,15 @@ int ll_add_int(LL *pl, char *key, int ival) {
|
|||||||
* thin wrapper for _ll_add_item
|
* thin wrapper for _ll_add_item
|
||||||
*/
|
*/
|
||||||
int ll_add_ll(LL *pl, char *key, LL *pnew) {
|
int ll_add_ll(LL *pl, char *key, LL *pnew) {
|
||||||
return _ll_add_item(pl,key,(void*)pnew,0,LL_TYPE_LL);
|
int result;
|
||||||
|
|
||||||
|
result = _ll_add_item(pl,key,(void*)pnew,0,LL_TYPE_LL);
|
||||||
|
if(result == LL_E_SUCCESS) {
|
||||||
|
if(pl->flags & LL_FLAG_INHERIT) {
|
||||||
|
pnew->flags = pl->flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,6 +123,11 @@ int ll_add_ll(LL *pl, char *key, LL *pnew) {
|
|||||||
int _ll_add_item(LL *pl, char *key, void* vpval, int ival, int type) {
|
int _ll_add_item(LL *pl, char *key, void* vpval, int ival, int type) {
|
||||||
LL_ITEM *pli;
|
LL_ITEM *pli;
|
||||||
|
|
||||||
|
if(pl->flags & LL_FLAG_NODUPS) {
|
||||||
|
if(ll_fetch_item(pl,key))
|
||||||
|
return LL_E_DUP;
|
||||||
|
}
|
||||||
|
|
||||||
pli=(LL_ITEM *)malloc(sizeof(LL_ITEM));
|
pli=(LL_ITEM *)malloc(sizeof(LL_ITEM));
|
||||||
if(!pli) {
|
if(!pli) {
|
||||||
return LL_E_MALLOC;
|
return LL_E_MALLOC;
|
||||||
@ -138,7 +155,11 @@ int _ll_add_item(LL *pl, char *key, void* vpval, int ival, int type) {
|
|||||||
pl->itemlist.next = pli;
|
pl->itemlist.next = pli;
|
||||||
} else {
|
} else {
|
||||||
pli->next = NULL;
|
pli->next = NULL;
|
||||||
pl->tailptr->next = pli;
|
if(pl->tailptr) {
|
||||||
|
pl->tailptr->next = pli;
|
||||||
|
} else {
|
||||||
|
pl->itemlist.next = pli;
|
||||||
|
}
|
||||||
pl->tailptr = pli;
|
pl->tailptr = pli;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,10 +181,11 @@ LL_ITEM *ll_fetch_item(LL *pl, char *key) {
|
|||||||
current = pl->itemlist.next;
|
current = pl->itemlist.next;
|
||||||
while(current) {
|
while(current) {
|
||||||
if(pl->flags & LL_FLAG_HONORCASE) {
|
if(pl->flags & LL_FLAG_HONORCASE) {
|
||||||
if(!strcasecmp(current->key,key))
|
|
||||||
break;
|
|
||||||
if(!strcmp(current->key,key))
|
if(!strcmp(current->key,key))
|
||||||
break;
|
return current;
|
||||||
|
} else {
|
||||||
|
if(!strcasecmp(current->key,key))
|
||||||
|
return current;
|
||||||
}
|
}
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
@ -198,7 +220,35 @@ int ll_get_flags(LL *pl, unsigned int *flags) {
|
|||||||
*
|
*
|
||||||
* @parm pl linked list to dump
|
* @parm pl linked list to dump
|
||||||
*/
|
*/
|
||||||
extern void ll_dump(LL *pl) {
|
void ll_dump(LL *pl) {
|
||||||
|
_ll_dump(pl,0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal support function for dumping linked list that
|
||||||
|
* carries depth.
|
||||||
|
*
|
||||||
|
* @param pl linked list to dump
|
||||||
|
* @param depth depth of list
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _ll_dump(LL *pl, int depth) {
|
||||||
|
LL_ITEM *pli;
|
||||||
|
pli = pl->itemlist.next;
|
||||||
|
while(pli) {
|
||||||
|
switch(pli->type) {
|
||||||
|
case LL_TYPE_INT:
|
||||||
|
printf("%*s%s (int): %d\n",depth*2,"",pli->key,pli->value.as_int);
|
||||||
|
break;
|
||||||
|
case LL_TYPE_STRING:
|
||||||
|
printf("%*s%s (string): %s\n",depth*2,"",pli->key,pli->value.as_string);
|
||||||
|
break;
|
||||||
|
case LL_TYPE_LL:
|
||||||
|
printf("%*s%s (list)\n",depth*2,"",pli->key);
|
||||||
|
_ll_dump(pli->value.as_ll,depth+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pli = pli->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4
src/ll.h
4
src/ll.h
@ -30,10 +30,12 @@
|
|||||||
#define LL_E_SUCCESS 0
|
#define LL_E_SUCCESS 0
|
||||||
#define LL_E_MALLOC 1
|
#define LL_E_MALLOC 1
|
||||||
#define LL_E_NOKEY 2
|
#define LL_E_NOKEY 2
|
||||||
|
#define LL_E_DUP 3
|
||||||
|
|
||||||
#define LL_FLAG_HONORCASE 1 /** Make keys case sensitive */
|
#define LL_FLAG_HONORCASE 1 /** Make keys case sensitive */
|
||||||
#define LL_FLAG_HEADINSERT 2 /** Insert at head, rather than tail */
|
#define LL_FLAG_HEADINSERT 2 /** Insert at head, rather than tail */
|
||||||
|
#define LL_FLAG_NODUPS 4 /** Do not allow duplicates */
|
||||||
|
#define LL_FLAG_INHERIT 8 /** Set child flags based on parent flags */
|
||||||
|
|
||||||
typedef struct _LLITEM {
|
typedef struct _LLITEM {
|
||||||
int type;
|
int type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user