mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-27 23:55:57 -05:00
Make compdirs work again, closing ticket #15
This commit is contained in:
parent
a06fa36c21
commit
9a396eca29
324
src/conf.c
324
src/conf.c
@ -74,14 +74,16 @@ typedef struct _CONF_ELEMENTS {
|
|||||||
|
|
||||||
/** Forwards */
|
/** Forwards */
|
||||||
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 *key);
|
||||||
static int _conf_exists(LL_HANDLE pll, char *section, char *term);
|
static int _conf_exists(LL_HANDLE pll, char *section, char *key);
|
||||||
static void _conf_lock(void);
|
static void _conf_lock(void);
|
||||||
static void _conf_unlock(void);
|
static void _conf_unlock(void);
|
||||||
static int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent);
|
static int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent);
|
||||||
static CONF_ELEMENTS *_conf_get_keyinfo(char *section, char *key);
|
static CONF_ELEMENTS *_conf_get_keyinfo(char *section, char *key);
|
||||||
static int _conf_makedir(char *path, char *user);
|
static int _conf_makedir(char *path, char *user);
|
||||||
static int _conf_existdir(char *path);
|
static int _conf_existdir(char *path);
|
||||||
|
static int _conf_split(char *s, char *delimiters, char ***argvp);
|
||||||
|
static void _conf_dispose_split(char **argv);
|
||||||
|
|
||||||
static CONF_ELEMENTS conf_elements[] = {
|
static CONF_ELEMENTS conf_elements[] = {
|
||||||
{ 1, 0, CONF_T_STRING,"general","runas" },
|
{ 1, 0, CONF_T_STRING,"general","runas" },
|
||||||
@ -130,7 +132,7 @@ int _conf_makedir(char *path,char *user) {
|
|||||||
|
|
||||||
pathdup=strdup(path);
|
pathdup=strdup(path);
|
||||||
if(!pathdup) {
|
if(!pathdup) {
|
||||||
DPRINTF(E_FATAL,L_CONF,"Malloc error\n");
|
DPRINTF(E_FATAL,L_CONF,"Malloc error\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
next_token=pathdup+1;
|
next_token=pathdup+1;
|
||||||
@ -141,21 +143,21 @@ int _conf_makedir(char *path,char *user) {
|
|||||||
strcat(path_buffer,"/");
|
strcat(path_buffer,"/");
|
||||||
strcat(path_buffer,token);
|
strcat(path_buffer,token);
|
||||||
|
|
||||||
if(!_conf_existdir(path_buffer)) {
|
if(!_conf_existdir(path_buffer)) {
|
||||||
/* FIXME: this is wrong -- it should really be 0700 owned by
|
/* FIXME: this is wrong -- it should really be 0700 owned by
|
||||||
* the runas user. That would require some os_ indirection
|
* the runas user. That would require some os_ indirection
|
||||||
*/
|
*/
|
||||||
DPRINTF(E_DBG,L_CONF,"Making %s\n",path_buffer);
|
DPRINTF(E_DBG,L_CONF,"Making %s\n",path_buffer);
|
||||||
if((mkdir(path_buffer,0700)) && (errno != EEXIST)) {
|
if((mkdir(path_buffer,0700)) && (errno != EEXIST)) {
|
||||||
free(pathdup);
|
free(pathdup);
|
||||||
DPRINTF(E_LOG,L_CONF,"Could not make dirctory %s: %s\n",
|
DPRINTF(E_LOG,L_CONF,"Could not make dirctory %s: %s\n",
|
||||||
path_buffer,strerror(errno));
|
path_buffer,strerror(errno));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
os_chown(path_buffer,user);
|
os_chown(path_buffer,user);
|
||||||
}
|
}
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pathdup);
|
free(pathdup);
|
||||||
@ -241,10 +243,10 @@ void _conf_unlock() {
|
|||||||
*
|
*
|
||||||
* @param pll top level linked list to test (config tree)
|
* @param pll top level linked list to test (config tree)
|
||||||
* @param section section to term (key) is in
|
* @param section section to term (key) is in
|
||||||
* @param term term/key to look for
|
* @param key key to look for
|
||||||
* @returns LL_ITEM of the key, or NULL
|
* @returns LL_ITEM of the key, or NULL
|
||||||
*/
|
*/
|
||||||
LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term) {
|
LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *key) {
|
||||||
LL_ITEM *psection;
|
LL_ITEM *psection;
|
||||||
LL_ITEM *pitem;
|
LL_ITEM *pitem;
|
||||||
|
|
||||||
@ -254,7 +256,7 @@ LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term) {
|
|||||||
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,key)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return pitem;
|
return pitem;
|
||||||
@ -265,11 +267,11 @@ LL_ITEM *_conf_fetch_item(LL_HANDLE pll, char *section, char *term) {
|
|||||||
*
|
*
|
||||||
* @param pll config tree to test
|
* @param pll config tree to test
|
||||||
* @param section section to find the term under
|
* @param section section to find the term under
|
||||||
* @param term key to search for under the specified section
|
* @param key key to search for under the specified section
|
||||||
* @returns TRUE if key exists, FALSE otherwise
|
* @returns TRUE if key exists, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
int _conf_exists(LL_HANDLE pll, char *section, char *term) {
|
int _conf_exists(LL_HANDLE pll, char *section, char *key) {
|
||||||
if(!_conf_fetch_item(pll,section,term))
|
if(!_conf_fetch_item(pll,section,key))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -312,37 +314,37 @@ int _conf_verify(LL_HANDLE pll) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(pce->type == CONF_T_EXISTPATH) {
|
if(pce->type == CONF_T_EXISTPATH) {
|
||||||
/* first, need to resolve */
|
/* first, need to resolve */
|
||||||
pi = _conf_fetch_item(pll,pce->section, pce->term);
|
pi = _conf_fetch_item(pll,pce->section, pce->term);
|
||||||
if(pi) {
|
if(pi) {
|
||||||
memset(resolved_path,0,sizeof(resolved_path));
|
memset(resolved_path,0,sizeof(resolved_path));
|
||||||
if(pi->value.as_string) {
|
if(pi->value.as_string) {
|
||||||
DPRINTF(E_SPAM,L_CONF,"Found %s/%s as %s... checking\n",
|
DPRINTF(E_SPAM,L_CONF,"Found %s/%s as %s... checking\n",
|
||||||
pce->section, pce->term, pi->value.as_string);
|
pce->section, pce->term, pi->value.as_string);
|
||||||
|
|
||||||
/* verify it exists, creating it if necessary */
|
/* verify it exists, creating it if necessary */
|
||||||
if(!_conf_existdir(pi->value.as_string)) {
|
if(!_conf_existdir(pi->value.as_string)) {
|
||||||
user = "nobody";
|
user = "nobody";
|
||||||
ptemp = _conf_fetch_item(pll, "general", "runas");
|
ptemp = _conf_fetch_item(pll, "general", "runas");
|
||||||
if(ptemp) {
|
if(ptemp) {
|
||||||
user = ptemp->value.as_string;
|
user = ptemp->value.as_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_conf_makedir(pi->value.as_string,user)) {
|
|
||||||
is_valid=0;
|
|
||||||
DPRINTF(E_LOG,L_CONF,"Can't make path %s, invalid config.\n",
|
|
||||||
resolved_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_conf_existdir(pi->value.as_string)) {
|
if(!_conf_makedir(pi->value.as_string,user)) {
|
||||||
realpath(pi->value.as_string,resolved_path);
|
is_valid=0;
|
||||||
free(pi->value.as_string);
|
DPRINTF(E_LOG,L_CONF,"Can't make path %s, invalid config.\n",
|
||||||
pi->value.as_string = strdup(resolved_path);
|
resolved_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DPRINTF(E_SPAM,L_CONF,"Resolved to %s\n",resolved_path);
|
if(_conf_existdir(pi->value.as_string)) {
|
||||||
}
|
realpath(pi->value.as_string,resolved_path);
|
||||||
}
|
free(pi->value.as_string);
|
||||||
|
pi->value.as_string = strdup(resolved_path);
|
||||||
|
|
||||||
|
DPRINTF(E_SPAM,L_CONF,"Resolved to %s\n",resolved_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pce++;
|
pce++;
|
||||||
@ -365,6 +367,7 @@ int conf_read(char *file) {
|
|||||||
FILE *fin;
|
FILE *fin;
|
||||||
int err;
|
int err;
|
||||||
LL_HANDLE pllnew, plltemp, pllcurrent, pllcomment;
|
LL_HANDLE pllnew, plltemp, pllcurrent, pllcomment;
|
||||||
|
LL_ITEM *pli;
|
||||||
char linebuffer[CONF_LINEBUFFER+1];
|
char linebuffer[CONF_LINEBUFFER+1];
|
||||||
char keybuffer[256];
|
char keybuffer[256];
|
||||||
char *comment, *term, *value, *delim;
|
char *comment, *term, *value, *delim;
|
||||||
@ -378,6 +381,8 @@ int conf_read(char *file) {
|
|||||||
int ws=0;
|
int ws=0;
|
||||||
CONF_ELEMENTS *pce;
|
CONF_ELEMENTS *pce;
|
||||||
int key_type;
|
int key_type;
|
||||||
|
char **valuearray;
|
||||||
|
int index;
|
||||||
|
|
||||||
if(conf_main_file) {
|
if(conf_main_file) {
|
||||||
conf_close();
|
conf_close();
|
||||||
@ -523,6 +528,30 @@ int conf_read(char *file) {
|
|||||||
|
|
||||||
switch(key_type) {
|
switch(key_type) {
|
||||||
case CONF_T_MULTICOMMA:
|
case CONF_T_MULTICOMMA:
|
||||||
|
/* first, see if we already have a tree... */
|
||||||
|
pli = ll_fetch_item(pllcurrent,term);
|
||||||
|
if(!pli) {
|
||||||
|
if((ll_create(&plltemp) != LL_E_SUCCESS)) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"Could not create "
|
||||||
|
"linked list.\n");
|
||||||
|
}
|
||||||
|
ll_add_ll(pllcurrent,term,plltemp);
|
||||||
|
ll_set_flags(plltemp,0); /* allow dups */
|
||||||
|
} else {
|
||||||
|
plltemp = pli->value.as_ll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* got list, break comma sep and add */
|
||||||
|
if(_conf_split(value,",",&valuearray) >= 0) {
|
||||||
|
index = 0;
|
||||||
|
while(valuearray[index]) {
|
||||||
|
ll_add_string(plltemp,term,valuearray[index]);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
_conf_dispose_split(valuearray);
|
||||||
|
} else {
|
||||||
|
ll_add_string(plltemp,term,value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CONF_T_INT:
|
case CONF_T_INT:
|
||||||
case CONF_T_STRING:
|
case CONF_T_STRING:
|
||||||
@ -730,18 +759,31 @@ int conf_get_string(char *section, char *key, char *dflt, char *out, int *size)
|
|||||||
* @returns a pointer to an allocated string containing the required
|
* @returns a pointer to an allocated string containing the required
|
||||||
* configuration key
|
* configuration key
|
||||||
*/
|
*/
|
||||||
char *conf_alloc_string (char *section, char *key, char *dflt) {
|
char *conf_alloc_string(char *section, char *key, char *dflt) {
|
||||||
int size = -1;
|
LL_ITEM *pitem;
|
||||||
char *out;
|
char *result;
|
||||||
|
char *retval;
|
||||||
|
|
||||||
/* FIXME: races */
|
_conf_lock();
|
||||||
conf_get_string(section, key, dflt, NULL, &size);
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
out = (char *)malloc(size * sizeof(char));
|
if((!pitem) || (pitem->type != LL_TYPE_STRING)) {
|
||||||
|
result = dflt;
|
||||||
|
} else {
|
||||||
|
result = pitem->value.as_string;
|
||||||
|
}
|
||||||
|
|
||||||
if(conf_get_string (section, key, dflt, out, &size) != CONF_E_SUCCESS)
|
if(result == NULL) {
|
||||||
return NULL;
|
_conf_unlock();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
retval = strdup(result);
|
||||||
|
|
||||||
|
if(!retval) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"Malloc error in conf_alloc_string\n");
|
||||||
|
}
|
||||||
|
_conf_unlock();
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -868,6 +910,8 @@ int conf_write(void) {
|
|||||||
int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent) {
|
int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent) {
|
||||||
LL_ITEM *pli;
|
LL_ITEM *pli;
|
||||||
LL_ITEM *ppre, *pin;
|
LL_ITEM *ppre, *pin;
|
||||||
|
LL_ITEM *plitemp;
|
||||||
|
|
||||||
char keybuffer[256];
|
char keybuffer[256];
|
||||||
|
|
||||||
if(!pll)
|
if(!pll)
|
||||||
@ -896,8 +940,11 @@ int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent) {
|
|||||||
switch(pli->type) {
|
switch(pli->type) {
|
||||||
case LL_TYPE_LL:
|
case LL_TYPE_LL:
|
||||||
if(sublevel) {
|
if(sublevel) {
|
||||||
/* something wrong! */
|
/* must be multivalued */
|
||||||
DPRINTF(E_LOG,L_CONF,"LL in sublevel: %s\n",pli->key);
|
plitemp = NULL;
|
||||||
|
while((plitemp = ll_get_next(pli->value.as_ll,plitemp))) {
|
||||||
|
fprintf(fp,"%s = %s\n",pli->key,plitemp->value.as_string);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp,"[%s]",pli->key);
|
fprintf(fp,"[%s]",pli->key);
|
||||||
if(pin) {
|
if(pin) {
|
||||||
@ -978,6 +1025,7 @@ int _conf_split(char *s, char *delimiters, char ***argvp) {
|
|||||||
const char *snew;
|
const char *snew;
|
||||||
char *t;
|
char *t;
|
||||||
char *tokptr;
|
char *tokptr;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
if ((s == NULL) || (delimiters == NULL) || (argvp == NULL))
|
if ((s == NULL) || (delimiters == NULL) || (argvp == NULL))
|
||||||
return -1;
|
return -1;
|
||||||
@ -989,8 +1037,13 @@ int _conf_split(char *s, char *delimiters, char ***argvp) {
|
|||||||
strcpy(t, snew);
|
strcpy(t, snew);
|
||||||
numtokens = 0;
|
numtokens = 0;
|
||||||
tokptr = NULL;
|
tokptr = NULL;
|
||||||
while(strtok_r(t,delimiters,&tokptr) != NULL)
|
tmp = t;
|
||||||
|
while(strtok_r(tmp,delimiters,&tokptr) != NULL) {
|
||||||
|
tmp=NULL;
|
||||||
numtokens++;
|
numtokens++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG,L_CONF,"Found %d tokens in %s\n",numtokens,s);
|
||||||
|
|
||||||
if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL) {
|
if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL) {
|
||||||
free(t);
|
free(t);
|
||||||
@ -1002,10 +1055,157 @@ int _conf_split(char *s, char *delimiters, char ***argvp) {
|
|||||||
else {
|
else {
|
||||||
strcpy(t, snew);
|
strcpy(t, snew);
|
||||||
tokptr = NULL;
|
tokptr = NULL;
|
||||||
for (i = 0; i < numtokens; i++)
|
tmp = t;
|
||||||
*((*argvp) + i) = strtok_r(t, delimiters, &tokptr);
|
for (i = 0; i < numtokens; i++) {
|
||||||
|
*((*argvp) + i) = strtok_r(tmp, delimiters, &tokptr);
|
||||||
|
tmp=NULL;
|
||||||
|
DPRINTF(E_DBG,L_CONF,"Token %d: %s\n",i+1,(*argvp)[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*((*argvp) + numtokens) = NULL;
|
*((*argvp) + numtokens) = NULL;
|
||||||
return numtokens;
|
return numtokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* implode a multivalued term in a perl sense.
|
||||||
|
*
|
||||||
|
* @param section section of term to implode
|
||||||
|
* @param key key of term to implode
|
||||||
|
* @pararm delimiter what to "glue" them with
|
||||||
|
* @returns imploded string (preallocated), or NULL
|
||||||
|
*/
|
||||||
|
char *conf_implode(char *section, char *key, char *delimiter) {
|
||||||
|
LL_ITEM *pitem;
|
||||||
|
LL_ITEM *penum;
|
||||||
|
int count;
|
||||||
|
int len;
|
||||||
|
char *retval;
|
||||||
|
|
||||||
|
_conf_lock();
|
||||||
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
|
if((!pitem) || (pitem->type != LL_TYPE_LL)) {
|
||||||
|
_conf_unlock();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* otherwise, alloc a string and go */
|
||||||
|
count = len = 0;
|
||||||
|
penum = NULL;
|
||||||
|
while((penum = ll_get_next(pitem->value.as_ll,penum))) {
|
||||||
|
if(penum->type != LL_TYPE_STRING) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"multivalued property not a string?\n");
|
||||||
|
}
|
||||||
|
len += strlen(penum->value.as_string);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!count) {
|
||||||
|
_conf_unlock();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += (strlen(delimiter) * (count-1));
|
||||||
|
retval = (char*)malloc(len + 1);
|
||||||
|
if(!retval) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"conf_implode: malloc\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(retval,0,len+1);
|
||||||
|
penum = NULL;
|
||||||
|
while((penum = ll_get_next(pitem->value.as_ll,penum))) {
|
||||||
|
strcat(retval,penum->value.as_string);
|
||||||
|
if(--count) {
|
||||||
|
strcat(retval,delimiter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_conf_unlock();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dispose of the argv set that was created in _conf_split
|
||||||
|
*
|
||||||
|
* @param argv string array to delete
|
||||||
|
*/
|
||||||
|
void _conf_dispose_split(char **argv) {
|
||||||
|
if(!argv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(argv[0])
|
||||||
|
free(argv[0]);
|
||||||
|
|
||||||
|
free(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a multi-valued item as an array (values)
|
||||||
|
*
|
||||||
|
* @param section section to fetch
|
||||||
|
* @param key multivalued key to get from array
|
||||||
|
* @returns TRUE on success, FALSE on failure
|
||||||
|
*/
|
||||||
|
int conf_get_array(char *section, char *key, char ***argvp) {
|
||||||
|
LL_ITEM *pitem, *penum;
|
||||||
|
int count;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
_conf_lock();
|
||||||
|
pitem = _conf_fetch_item(conf_main,section,key);
|
||||||
|
if((!pitem) || (pitem->type != LL_TYPE_LL)) {
|
||||||
|
_conf_unlock();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* otherwise, alloc a string and go */
|
||||||
|
count = 0;
|
||||||
|
penum = NULL;
|
||||||
|
while((penum = ll_get_next(pitem->value.as_ll,penum))) {
|
||||||
|
if(penum->type != LL_TYPE_STRING) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"multivalued property not a string?\n");
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we have a count, alloc an argv */
|
||||||
|
len = (count+1) * sizeof(char*);
|
||||||
|
*(argvp) = (char**)malloc(len);
|
||||||
|
if(!*(argvp)) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"conf_get_array: malloc\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(*(argvp),0,len);
|
||||||
|
|
||||||
|
count=0;
|
||||||
|
penum=NULL;
|
||||||
|
while((penum = ll_get_next(pitem->value.as_ll,penum))) {
|
||||||
|
(*argvp)[count] = strdup(penum->value.as_string);
|
||||||
|
if(!(*argvp)[count]) {
|
||||||
|
DPRINTF(E_FATAL,L_CONF,"conf_get_array: malloc\n");
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_conf_unlock();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dispose of the array created above
|
||||||
|
*
|
||||||
|
* @param argv argv pointer created
|
||||||
|
*/
|
||||||
|
void conf_dispose_array(char **argv) {
|
||||||
|
int index=0;
|
||||||
|
|
||||||
|
if(!argv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
while(argv[index]) {
|
||||||
|
free(argv[index]);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,4 +45,7 @@ extern int conf_isset(char *section, char *key);
|
|||||||
extern int conf_iswritable(void);
|
extern int conf_iswritable(void);
|
||||||
extern int conf_write(void);
|
extern int conf_write(void);
|
||||||
|
|
||||||
|
extern char *conf_implode(char *section, char *key, char *delimiter);
|
||||||
|
extern int conf_get_array(char *section, char *key, char ***argvp);
|
||||||
|
extern void conf_dispose_array(char **argv);
|
||||||
#endif /* _CONFIG_H_ */
|
#endif /* _CONFIG_H_ */
|
||||||
|
@ -261,22 +261,24 @@ int scan_init(char *path) {
|
|||||||
* check to see if a particular path is a complation path
|
* check to see if a particular path is a complation path
|
||||||
*
|
*
|
||||||
* @param path path to check
|
* @param path path to check
|
||||||
* @returns 1 if it is a compilation path, 0 otherwise
|
* @returns TRUE if it is a compilation path, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
int scan_is_compdir(char *path) {
|
int scan_is_compdir(char *path) {
|
||||||
#if 0
|
|
||||||
int current=0;
|
int current=0;
|
||||||
|
char **compdirs;
|
||||||
|
|
||||||
if(!config.complist)
|
if(!conf_get_array("general","compdirs",&compdirs))
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
while(config.complist[current]) {
|
while(compdirs[current]) {
|
||||||
if(strcasestr(path,config.complist[current]))
|
if(strcasestr(path,compdirs[current])) {
|
||||||
return 1;
|
conf_dispose_array(compdirs);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
current++;
|
current++;
|
||||||
}
|
}
|
||||||
#endif
|
conf_dispose_array(compdirs);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -660,7 +662,7 @@ void make_composite_tags(MP3FILE *song) {
|
|||||||
|
|
||||||
if(!song->artist) {
|
if(!song->artist) {
|
||||||
if (song->orchestra && song->conductor) {
|
if (song->orchestra && song->conductor) {
|
||||||
len = (int)strlen(song->orchestra) +
|
len = (int)strlen(song->orchestra) +
|
||||||
(int)strlen(sep) +
|
(int)strlen(sep) +
|
||||||
(int)strlen(song->conductor);
|
(int)strlen(song->conductor);
|
||||||
ptmp = (char*)malloc(len + 1);
|
ptmp = (char*)malloc(len + 1);
|
||||||
@ -685,7 +687,7 @@ void make_composite_tags(MP3FILE *song) {
|
|||||||
sprintf(ptmp,"%s%s%s",song->artist, sep, song->title);
|
sprintf(ptmp,"%s%s%s",song->artist, sep, song->title);
|
||||||
free(song->title);
|
free(song->title);
|
||||||
song->title = ptmp;
|
song->title = ptmp;
|
||||||
|
|
||||||
if(va_artist) {
|
if(va_artist) {
|
||||||
ptmp = strdup(va_artist);
|
ptmp = strdup(va_artist);
|
||||||
if(ptmp) {
|
if(ptmp) {
|
||||||
@ -695,7 +697,7 @@ void make_composite_tags(MP3FILE *song) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(song->url)
|
if(song->url)
|
||||||
song->data_kind=1;
|
song->data_kind=1;
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user