config file upgrading

This commit is contained in:
Ron Pedde 2006-03-13 06:33:58 +00:00
parent 9bb208e156
commit be7bdfbbfb
2 changed files with 195 additions and 19 deletions

View File

@ -48,6 +48,8 @@
/** Globals */ /** Globals */
//static int ecode; //static int ecode;
static LL_HANDLE conf_main=NULL; static LL_HANDLE conf_main=NULL;
static LL_HANDLE conf_comments=NULL;
static char *conf_main_file = NULL; static char *conf_main_file = NULL;
static pthread_mutex_t conf_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t conf_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -63,7 +65,7 @@ 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_lock(void);
static void _conf_unlock(void); static void _conf_unlock(void);
static int _conf_write(FILE *fp, LL *pll, int sublevel); static int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent);
typedef struct _CONF_ELEMENTS { typedef struct _CONF_ELEMENTS {
int required; int required;
@ -193,9 +195,11 @@ int _conf_verify(LL_HANDLE pll) {
} }
} }
if(pce->deprecated) { if(pce->deprecated) {
DPRINTF(E_LOG,L_CONF,"Config entry %s/%s is deprecated. Please " if(_conf_exists(pll,pce->section,pce->term)) {
"review the sample config\n", DPRINTF(E_LOG,L_CONF,"Config entry %s/%s is deprecated. Please "
pce->section, pce->term); "review the sample config\n",
pce->section, pce->term);
}
} }
if(pce->type == CONF_T_EXISTPATH) { if(pce->type == CONF_T_EXISTPATH) {
/* first, need to resolve */ /* first, need to resolve */
@ -231,11 +235,14 @@ int conf_read(char *file) {
int err; int err;
LL_HANDLE pllnew, plltemp, pllcurrent, pllcomment; LL_HANDLE pllnew, plltemp, pllcurrent, pllcomment;
char linebuffer[CONF_LINEBUFFER+1]; char linebuffer[CONF_LINEBUFFER+1];
char keybuffer[256];
char *comment, *term, *value, *delim; char *comment, *term, *value, *delim;
char *running_comment=NULL; char *section_name=NULL;
char *prev_comments=NULL;
int prev_comment_length=20;
int compat_mode=1; int compat_mode=1;
int line=0; int line=0;
int ws=0;
if(conf_main_file) { if(conf_main_file) {
conf_close(); conf_close();
@ -248,6 +255,9 @@ int conf_read(char *file) {
return CONF_E_FOPEN; return CONF_E_FOPEN;
} }
prev_comments = (char*)malloc(prev_comment_length);
prev_comments[0] = '\0';
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);
@ -255,6 +265,7 @@ int conf_read(char *file) {
} }
ll_create(&pllcomment); /* don't care if we lose comments */ ll_create(&pllcomment); /* don't care if we lose comments */
comment = NULL; comment = NULL;
pllcurrent=NULL; pllcurrent=NULL;
@ -264,6 +275,7 @@ int conf_read(char *file) {
while(fgets(linebuffer,CONF_LINEBUFFER,fin)) { while(fgets(linebuffer,CONF_LINEBUFFER,fin)) {
line++; line++;
linebuffer[CONF_LINEBUFFER] = '\0'; linebuffer[CONF_LINEBUFFER] = '\0';
ws=0;
comment=strchr(linebuffer,'#'); comment=strchr(linebuffer,'#');
if(comment) { if(comment) {
@ -271,7 +283,8 @@ int conf_read(char *file) {
comment++; comment++;
} }
while(strlen(linebuffer) && (strchr("\n\r ",linebuffer[strlen(linebuffer)-1]))) while(strlen(linebuffer) &&
(strchr("\n\r ",linebuffer[strlen(linebuffer)-1])))
linebuffer[strlen(linebuffer)-1] = '\0'; linebuffer[strlen(linebuffer)-1] = '\0';
if(linebuffer[0] == '[') { if(linebuffer[0] == '[') {
@ -293,7 +306,27 @@ int conf_read(char *file) {
} }
ll_add_ll(pllnew,term,plltemp); ll_add_ll(pllnew,term,plltemp);
/* set current section and name */
pllcurrent = plltemp; pllcurrent = plltemp;
if(section_name)
free(section_name);
section_name = strdup(term);
/* set precomments */
if(prev_comments[0] != '\0') {
/* we had some preceding comments */
snprintf(keybuffer,sizeof(keybuffer),"pre_%s",section_name);
ll_add_string(pllcomment,keybuffer,prev_comments);
prev_comments[0] = '\0';
}
if(comment) {
/* we had some preceding comments */
snprintf(keybuffer,sizeof(keybuffer),"in_%s",section_name);
ll_add_string(pllcomment,keybuffer,comment);
prev_comments[0] = '\0';
comment = NULL;
}
} else { } else {
/* k/v pair */ /* k/v pair */
term=&linebuffer[0]; term=&linebuffer[0];
@ -311,28 +344,106 @@ int conf_read(char *file) {
strsep(&value,delim); strsep(&value,delim);
if((value) && (term) && (strlen(term))) { if((value) && (term) && (strlen(term))) {
while((strlen(term) && (strchr("\t ",term[strlen(term)-1]))))
term[strlen(term)-1] = '\0';
while(strlen(value) && (strchr("\t ",*value))) while(strlen(value) && (strchr("\t ",*value)))
value++; value++;
while((strlen(value) && (strchr("\t ",value[strlen(value)-1]))))
value[strlen(value)-1] = '\0';
if(!pllcurrent) { if(!pllcurrent) {
/* we are definately in compat mode -- add a general section */ /* in compat mode -- add a general section */
if((err=ll_create(&plltemp)) != LL_E_SUCCESS) { if((err=ll_create(&plltemp)) != LL_E_SUCCESS) {
DPRINTF(E_LOG,L_CONF,"Error creating linked list: %d\n",err); DPRINTF(E_LOG,L_CONF,"Error creating list: %d\n",err);
ll_destroy(pllnew); ll_destroy(pllnew);
fclose(fin); fclose(fin);
return CONF_E_UNKNOWN; return CONF_E_UNKNOWN;
} }
ll_add_ll(pllnew,"general",plltemp); ll_add_ll(pllnew,"general",plltemp);
pllcurrent = plltemp; pllcurrent = plltemp;
if(section_name)
free(section_name); /* shouldn't ahppen */
section_name = strdup("general");
/* no inline comments, just precomments */
if(prev_comments[0] != '\0') {
/* we had some preceding comments */
ll_add_string(pllcomment,"pre_general",prev_comments);
prev_comments[0] = '\0';
}
} }
ll_add_string(pllcurrent,term,value); ll_add_string(pllcurrent,term,value);
if(comment) {
/* this is an inline comment */
snprintf(keybuffer,sizeof(keybuffer),"in_%s_%s",
section_name,term);
DPRINTF(E_SPAM,L_CONF,"Adding %s: %s\n",keybuffer,comment);
ll_add_string(pllcomment,keybuffer,comment);
comment = NULL;
}
if(prev_comments[0] != '\0') {
/* we had some preceding comments */
snprintf(keybuffer,sizeof(keybuffer),"pre_%s_%s",
section_name, term);
DPRINTF(E_SPAM,L_CONF,"Adding %s: %s\n",keybuffer,
prev_comments);
ll_add_string(pllcomment,keybuffer,prev_comments);
prev_comments[0] = '\0';
}
} else {
ws=1;
} }
if(((term) && (strlen(term))) && (!value)) { if(((term) && (strlen(term))) && (!value)) {
DPRINTF(E_LOG,L_CONF,"Error in config file on line %d\n",line); DPRINTF(E_LOG,L_CONF,"Error in config file on line %d\n",line);
ll_destroy(pllnew); ll_destroy(pllnew);
return CONF_E_PARSE; return CONF_E_PARSE;
} }
} }
if((comment)||(ws)) {
if(!comment)
comment = "";
DPRINTF(E_SPAM,L_CONF,"found comment: %s\n",comment);
/* add to prev comments */
if((int)strlen(comment) + 2 >=
(prev_comment_length - (int)strlen(prev_comments))) {
/* need to expand the buffer */
if(prev_comment_length < 32768) {
prev_comment_length *= 2;
DPRINTF(E_SPAM,L_CONF,"Expanding precomments to %d\n",
prev_comment_length);
prev_comments=realloc(prev_comments,prev_comment_length);
if(!prev_comments)
DPRINTF(E_FATAL,L_CONF,"Malloc error\n");
}
}
if(strlen(comment)) {
strcat(prev_comments,"#");
strcat(prev_comments,comment);
} else {
strcat(prev_comments,"\n");
}
DPRINTF(E_SPAM,L_CONF,"Current comment block: \n%s\n",prev_comments);
}
}
if(section_name)
free(section_name);
if(prev_comments) {
if(prev_comments[0] != '\0') {
ll_add_string(pllcomment,"end",prev_comments);
}
free(prev_comments);
} }
fclose(fin); fclose(fin);
@ -344,10 +455,17 @@ int conf_read(char *file) {
if(conf_main) { if(conf_main) {
ll_destroy(conf_main); ll_destroy(conf_main);
} }
if(conf_comments) {
ll_destroy(conf_comments);
}
conf_main = pllnew; conf_main = pllnew;
conf_comments = pllcomment;
_conf_unlock(); _conf_unlock();
} else { } else {
ll_destroy(pllnew); ll_destroy(pllnew);
ll_destroy(pllcomment);
DPRINTF(E_LOG,L_CONF,"Could not validate config file. Ignoring\n"); DPRINTF(E_LOG,L_CONF,"Could not validate config file. Ignoring\n");
} }
@ -363,6 +481,11 @@ int conf_close(void) {
conf_main = NULL; conf_main = NULL;
} }
if(conf_comments) {
ll_destroy(conf_comments);
conf_comments = NULL;
}
if(conf_main_file) { if(conf_main_file) {
free(conf_main_file); free(conf_main_file);
conf_main_file = NULL; conf_main_file = NULL;
@ -544,7 +667,7 @@ int conf_write(void) {
_conf_lock(); _conf_lock();
if((fp = fopen(conf_main_file,"w+")) != NULL) { if((fp = fopen(conf_main_file,"w+")) != NULL) {
retval = _conf_write(fp,conf_main,0); retval = _conf_write(fp,conf_main,0,NULL);
fclose(fp); fclose(fp);
} }
_conf_unlock(); _conf_unlock();
@ -560,8 +683,10 @@ int conf_write(void) {
* @param sublevel whether this is the root, or a subkey * @param sublevel whether this is the root, or a subkey
* @returns TRUE on success, FALSE otherwise * @returns TRUE on success, FALSE otherwise
*/ */
int _conf_write(FILE *fp, LL *pll, int sublevel) { int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent) {
LL_ITEM *pli; LL_ITEM *pli;
LL_ITEM *ppre, *pin;
char keybuffer[256];
if(!pll) if(!pll)
return TRUE; return TRUE;
@ -569,29 +694,67 @@ int _conf_write(FILE *fp, LL *pll, int sublevel) {
/* write all the solo keys, first! */ /* write all the solo keys, first! */
pli = pll->itemlist.next; pli = pll->itemlist.next;
while(pli) { while(pli) {
/* if there is a PRE there, then let's emit that*/
if(sublevel) {
snprintf(keybuffer,sizeof(keybuffer),"pre_%s_%s",parent,pli->key);
ppre=ll_fetch_item(conf_comments,keybuffer);
snprintf(keybuffer,sizeof(keybuffer),"in_%s_%s",parent,pli->key);
pin = ll_fetch_item(conf_comments,keybuffer);
} else {
snprintf(keybuffer,sizeof(keybuffer),"pre_%s",pli->key);
ppre=ll_fetch_item(conf_comments,keybuffer);
snprintf(keybuffer,sizeof(keybuffer),"in_%s",pli->key);
pin = ll_fetch_item(conf_comments,keybuffer);
}
if(ppre) {
fprintf(fp,"%s",ppre->value.as_string);
}
switch(pli->type) { switch(pli->type) {
case LL_TYPE_LL: case LL_TYPE_LL:
if(sublevel) { if(sublevel) {
/* something wrong! */ /* something wrong! */
DPRINTF(E_LOG,L_CONF,"LL in sublevel: %s\n",pli->key); DPRINTF(E_LOG,L_CONF,"LL in sublevel: %s\n",pli->key);
} else { } else {
fprintf(fp,"[%s]\n",pli->key); fprintf(fp,"[%s]",pli->key);
if(!_conf_write(fp, pli->value.as_ll, 1)) if(pin) {
fprintf(fp," #%s",pin->value.as_string);
}
fprintf(fp,"\n");
if(!_conf_write(fp, pli->value.as_ll, 1, pli->key))
return FALSE; return FALSE;
} }
break; break;
case LL_TYPE_INT: case LL_TYPE_INT:
fprintf(fp,"%s=%d\n",pli->key,pli->value.as_int); fprintf(fp,"%s = %d",pli->key,pli->value.as_int);
if(pin) {
fprintf(fp," #%s",pin->value.as_string);
}
fprintf(fp,"\n");
break; break;
case LL_TYPE_STRING: case LL_TYPE_STRING:
fprintf(fp,"%s=%s\n",pli->key,pli->value.as_string); fprintf(fp,"%s = %s",pli->key,pli->value.as_string);
if(pin) {
fprintf(fp," #%s",pin->value.as_string);
}
fprintf(fp,"\n");
break; break;
} }
pli = pli->next; pli = pli->next;
} }
if(!sublevel) {
pin = ll_fetch_item(conf_comments,"end");
if(pin) {
fprintf(fp,"%s",pin->value.as_string);
}
}
return TRUE; return TRUE;
} }
@ -605,13 +768,13 @@ int _conf_write(FILE *fp, LL *pll, int sublevel) {
*/ */
int conf_isset(char *section, char *key) { int conf_isset(char *section, char *key) {
int retval = FALSE; int retval = FALSE;
_conf_lock(); _conf_lock();
if(_conf_fetch_item(conf_main,section,key)) { if(_conf_fetch_item(conf_main,section,key)) {
retval = TRUE; retval = TRUE;
} }
_conf_unlock(); _conf_unlock();
return retval; return retval;
} }

View File

@ -196,6 +196,7 @@ int main(int argc, char *argv[]) {
int force_non_root=0; int force_non_root=0;
int skip_initial=0; int skip_initial=0;
int size; int size;
int convert_conf=0;
char logfile[PATH_MAX]; char logfile[PATH_MAX];
char db_type[40]; char db_type[40];
char db_parms[PATH_MAX]; char db_parms[PATH_MAX];
@ -214,7 +215,7 @@ int main(int argc, char *argv[]) {
err_setlevel(1); err_setlevel(1);
config.foreground=0; config.foreground=0;
while((option=getopt(argc,argv,"D:d:c:P:mfrysiu")) != -1) { while((option=getopt(argc,argv,"D:d:c:P:mfrysiuv")) != -1) {
switch(option) { switch(option) {
case 'd': case 'd':
err_setlevel(atoi(optarg)); err_setlevel(atoi(optarg));
@ -265,6 +266,9 @@ int main(int argc, char *argv[]) {
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
#endif #endif
case 'v':
convert_conf=1;
break;
default: default:
usage(argv[0]); usage(argv[0]);
@ -273,7 +277,7 @@ int main(int argc, char *argv[]) {
} }
} }
if((getuid()) && (!force_non_root)) { if((getuid()) && (!force_non_root) && (!convert_conf)) {
fprintf(stderr,"You are not root. This is almost certainly wrong. If you are\n" fprintf(stderr,"You are not root. This is almost certainly wrong. If you are\n"
"sure you want to do this, use the -y command-line switch\n"); "sure you want to do this, use the -y command-line switch\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -289,6 +293,15 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if(convert_conf) {
fprintf(stderr,"Converting config file...\n");
if(!conf_write()) {
fprintf(stderr,"Error writing config file.\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
DPRINTF(E_LOG,L_MAIN,"Starting with debuglevel %d\n",err_getlevel()); DPRINTF(E_LOG,L_MAIN,"Starting with debuglevel %d\n",err_getlevel());
if(!config.foreground) { if(!config.foreground) {