68
68
#endif /* WITH_LDAP_SUPPORT */
70
/**** EXTERNAL FUNCTIONS ****/
72
int config_read_file( char *filename )
71
/**** PUBLIC FUNCTIONS ****/
73
/** Parse configuration from INI-file style config file into memory.
74
* \param filename Name of the config file.
75
* \returns 0 : config successfully parsed
76
* \returns <0 : error occurred
78
int config_read_file(const char *filename)
75
section * curr_section = NULL;
81
section *curr_section = NULL;
77
84
#ifdef WITH_LDAP_SUPPORT
78
LDAPURLDesc * url = NULL;
85
LDAPURLDesc *url = NULL;
80
87
#endif /* WITH_LDAP_SUPPORT */
82
report( RPT_NOTICE, "Using Configuration File: %s", filename);
89
report(RPT_NOTICE, "Using Configuration File: %s", filename);
84
91
#ifdef WITH_LDAP_SUPPORT
85
if (ldap_is_ldap_url( filename )) {
88
if (0 != (retval = ldap_url_parse( filename, &url))) {
89
report( RPT_ERR, "Errors parsing LDAP URL %s: %s", filename, ldap_err2string(retval));
92
if (ldap_is_ldap_url(filename)) {
95
if (0 != (retval = ldap_url_parse(filename, &url))) {
96
report(RPT_ERR, "Errors parsing LDAP URL %s: %s", filename, ldap_err2string(retval));
90
97
ldap_free_urldesc(url);
94
ldap_host=strdup(url->lud_host);
95
ldap_port=url->lud_port;
96
report( RPT_INFO, "Using LDAP server: %s:%d", ldap_host, ldap_port);
101
ldap_host = strdup(url->lud_host);
102
ldap_port = url->lud_port;
103
report(RPT_INFO, "Using LDAP server: %s:%d", ldap_host, ldap_port);
98
ldap_base_dn=strdup(url->lud_dn);
99
report( RPT_INFO, "Using LDAP base DN: %s", ldap_base_dn);
105
ldap_base_dn = strdup(url->lud_dn);
106
report(RPT_INFO, "Using LDAP base DN: %s", ldap_base_dn);
101
108
ldap_free_urldesc(url);
103
if (connect_to_ldap() < 0 ) {
104
debug( RPT_DEBUG, "connect_to_ldap returned errors.");
110
if (connect_to_ldap() < 0) {
111
debug(RPT_DEBUG, "connect_to_ldap returned errors.");
110
117
#endif /* WITH_LDAP_SUPPORT */
112
f = buffile_open( filename, "r" );
119
f = fopen(filename, "r");
117
process_config( &curr_section, get_next_char_f, 1, filename, f );
124
result = process_config(&curr_section, get_next_char_f, filename, f);
125
int config_read_string( char *sectionname, char *str )
132
int config_read_string(const char *sectionname, const char *str)
126
133
/* All the config parameters are placed in the given section in memory.*/
131
138
/* We use a nested fuction to transfer the characters from buffer to parser*/
132
139
char get_next_char() {
133
140
return str[pos++];
136
if( !( s=find_section( sectionname ))) {
137
s=add_section( sectionname );
140
process_config( &s, get_next_char, 0, "command line", NULL );
143
if ((s = find_section(sectionname)) == NULL)
144
s = add_section(sectionname);
146
return process_config(&s, get_next_char, "command line", NULL);
146
char *config_get_string( char * sectionname, char * keyname,
147
int skip, char * default_value )
150
/** Get string from configuration in memory.
151
* \param sectionname Name of the section where the key is sought.
152
* \param keyname Name of the key to look for.
153
* \param skip Number of values to skip/ignore before returning the value.
154
* \param default_value Default value if section/key is not found.
155
* \return Value found / default value
157
const char *config_get_string(const char *sectionname, const char *keyname,
158
int skip, const char *default_value)
160
key *k = find_key(find_section(sectionname), keyname, skip);
152
s = find_section( sectionname );
153
if( !s ) return default_value;
154
k = find_key( s, keyname, skip );
155
if( !k ) return default_value;
163
return default_value;
161
169
/* Reallocate memory space for the return value*/
163
string_storage = realloc( string_storage, ( strlen( k->value ) / 256 + 1) * 256 );
164
strcpy( string_storage, k->value );
171
string_storage = realloc(string_storage,(strlen(k->value) / 256 + 1) * 256);
172
strcpy(string_storage, k->value);
166
174
But then you also need a global static string_storage = NULL;
171
short config_get_bool( char *sectionname, char *keyname,
172
int skip, short default_value )
179
/** Get boolean value from configuration in memory.
180
* \param sectionname Name of the section where the key is sought.
181
* \param keyname Name of the key to look for.
182
* \param skip Number of values to skip/ignore before returning the value.
183
* \param default_value Default value if section/key is not found or value is no legal boolean.
184
* \return Value found / default value
186
short config_get_bool(const char *sectionname, const char *keyname,
187
int skip, short default_value)
177
s = find_section( sectionname );
178
if( !s ) return default_value;
179
k = find_key( s, keyname, skip );
180
if( !k ) return default_value;
182
if( strcasecmp( k->value, "0" )==0 || strcasecmp( k->value, "false" )==0
183
|| strcasecmp( k->value, "n" )==0 || strcasecmp( k->value, "no" )==0 ) {
189
key *k = find_key(find_section(sectionname), keyname, skip);
192
return default_value;
194
if (strcasecmp(k->value, "0") == 0 || strcasecmp(k->value, "false") == 0
195
|| strcasecmp(k->value, "n") == 0 || strcasecmp(k->value, "no") == 0
196
|| strcasecmp(k->value, "off") == 0) {
186
if( strcasecmp( k->value, "1" )==0 || strcasecmp( k->value, "true" )==0
187
|| strcasecmp( k->value, "y" )==0 || strcasecmp( k->value, "yes" )==0 ) {
199
if (strcasecmp(k->value, "1") == 0 || strcasecmp(k->value, "true") == 0
200
|| strcasecmp(k->value, "y") == 0 || strcasecmp(k->value, "yes") == 0
201
|| strcasecmp(k->value, "on") == 0) {
190
204
return default_value;
194
long int config_get_int( char *sectionname, char *keyname,
195
int skip, long int default_value )
202
s = find_section( sectionname );
203
if( !s ) return default_value;
204
k = find_key( s, keyname, skip );
205
if( !k ) return default_value;
207
v = strtol( k->value, &v_end, 0 );
208
if( v_end-(k->value) != strlen(k->value) ) {
209
/* Conversion not succesful*/
210
return default_value;
216
double config_get_float( char *sectionname, char *keyname,
217
int skip, double default_value )
224
s = find_section( sectionname );
225
if( !s ) return default_value;
226
k = find_key( s, keyname, skip );
227
if( !k ) return default_value;
229
v = strtod( k->value, &v_end );
230
if( v_end-(k->value) != strlen(k->value) ) {
231
/* Conversion not succesful*/
232
return default_value;
238
int config_has_section( char *sectionname )
242
s = find_section( sectionname );
243
if( s ) return 1; else return 0;
247
int config_has_key( char *sectionname, char *keyname )
208
/** Get integer from configuration in memory.
209
* \param sectionname Name of the section where the key is sought.
210
* \param keyname Name of the key to look for.
211
* \param skip Number of values to skip/ignore before returning the value.
212
* \param default_value Default value if section/key is not found or value is no integer.
213
* \return Value found / default value
215
long int config_get_int(const char *sectionname, const char *keyname,
216
int skip, long int default_value)
218
key *k = find_key(find_section(sectionname), keyname, skip);
222
long int v = strtol(k->value, &end, 0);
224
if ((end != NULL) && (end != k->value) && (*end == '\0'))
225
/* Conversion succesful */
228
return default_value;
232
/** Get floating point number from configuration in memory.
233
* \param sectionname Name of the section where the key is sought.
234
* \param keyname Name of the key to look for.
235
* \param skip Number of values to skip/ignore before returning the value.
236
* \param default_value Default value if section/key is not found or value is no floating point number.
237
* \return Value found / default value
239
double config_get_float(const char *sectionname, const char *keyname,
240
int skip, double default_value)
242
key *k = find_key(find_section(sectionname), keyname, skip);
246
double v = strtod(k->value, &end);
248
if ((end != NULL) && (end != k->value) && (*end == '\0'))
249
/* Conversion succesful*/
252
return default_value;
256
/** Test whether the configuration containis a specific section.
257
* \param sectionname Name of the section to look for.
258
* \return 0 = section not in config; 1 = section in config
260
int config_has_section(const char *sectionname)
262
return (find_section(sectionname) != NULL) ? 1 : 0;
266
/** Test whether the configuration contains a specific key in a specfic section.
267
* \param sectionname Name of the section where the key is sought.
268
* \param keyname Name of the key to look for.
269
* \return 0 = key or section not found; n = key found with n values
271
int config_has_key(const char *sectionname, const char *keyname)
273
section *s = find_section(sectionname);
254
s = find_section( sectionname );
257
for( k=s->first_key; k; k=k->next_key ) {
259
/* Did we find the right key ?*/
260
if( strcasecmp( k->name, keyname ) == 0 ) {
279
for (k = s->first_key; k != NULL; k = k->next_key) {
280
/* Did we find the right key ?*/
281
if (strcasecmp(k->name, keyname) == 0)
289
/** Clear configuration. */
268
290
void config_clear()
275
for( s = first_section; s; ) {
276
for( k=s->first_key; k; ) {
295
for (s = first_section; s != NULL; s = next_s) {
299
for (k = s->first_key; k != NULL; k = next_k) {
277
300
/* Advance before we destroy the current key */
278
301
next_k = k->next_key;
286
307
/* Advance before we destroy the current section */
287
308
next_s = s->next_section;
289
310
/* And destroy it */
295
/* And make everything inaccessable */
314
/* Finally make everything inaccessable */
296
315
first_section = NULL;
300
319
/**** INTERNAL FUNCTIONS ****/
302
321
#ifdef WITH_LDAP_SUPPORT
304
connect_to_ldap (void)
323
connect_to_ldap(void)
309
debug( RPT_INFO, "Connecting to LDAP server: %s:%d", ldap_host, ldap_port);
328
debug(RPT_INFO, "Connecting to LDAP server: %s:%d", ldap_host, ldap_port);
311
330
if (!(ld = ldap_init(ldap_host, ldap_port))) {
312
331
report(RPT_ERR, "LDAP session could not be initialized.");
316
335
/*****************************************************
317
336
* disabled unless you really have a DN/pwd to bind to
318
337
* WARNING: LCDd should not have LDAP write access!!
320
* if (LDAP_SUCCESS != (retval = ldap_simple_bind_s (ld, ldap_user, ldap_pwd))) {
321
* report (RPT_ERR, "LDAP login on %s:%d failed: %s", ldap_host, ldap_port, ldap_err2string (retval));
339
* if (LDAP_SUCCESS != (retval = ldap_simple_bind_s(ld, ldap_user, ldap_pwd))) {
340
* report(RPT_ERR, "LDAP login on %s:%d failed: %s", ldap_host, ldap_port, ldap_err2string(retval));
327
346
* fprintf(stderr, "LDAP login successful on %s:%d\n", ldap_host, ldap_port);
328
347
********************************************************/
330
349
/* check for the existence of the config object... */
331
if (LDAP_SUCCESS != (retval = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_BASE, "objectClass=lcdprocConfig", NULL, 0, &res))) {
332
report( RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
350
if (LDAP_SUCCESS != (retval = ldap_search_s(ld, ldap_base_dn, LDAP_SCOPE_BASE, "objectClass=lcdprocConfig", NULL, 0, &res))) {
351
report(RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
335
354
if (0 == ldap_count_entries(ld, res)) {
336
report( RPT_ERR, "No configuration object found in LDAP at: %s", ldap_base_dn);
355
report(RPT_ERR, "No configuration object found in LDAP at: %s", ldap_base_dn);
339
debug( RPT_DEBUG, "Configuration LDAP object found.");
358
debug(RPT_DEBUG, "Configuration LDAP object found.");
343
362
#define BUFSIZE 255
344
363
#endif /* WITH_LDAP_SUPPORT */
346
section * find_section( char * sectionname )
366
static section *find_section(const char *sectionname)
350
370
#ifdef WITH_LDAP_SUPPORT
356
debug( RPT_DEBUG, "Searching LDAP for section [%s]", sectionname);
376
debug(RPT_DEBUG, "Searching LDAP for section [%s]", sectionname);
357
377
if (NULL == (filter = malloc(BUFSIZE))){
358
report( RPT_ERR, "Could not allocate memory in find_section()");
378
report(RPT_ERR, "Could not allocate memory in find_section()");
361
381
strcpy(filter, "cn=");
362
382
strncat(filter, sectionname, BUFSIZE);
363
if (LDAP_SUCCESS != (retval = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &res))) {
383
if (LDAP_SUCCESS != (retval = ldap_search_s(ld, ldap_base_dn, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &res))) {
364
384
if (NULL != filter) {
368
388
ldap_msgfree(res);
369
report( RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
389
report(RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
372
392
if (NULL != filter) {
376
if (0 == ldap_count_entries( ld, res )) {
377
debug( RPT_DEBUG, "Section [%s] not found in LDAP.", sectionname);
396
if (0 == ldap_count_entries(ld, res)) {
397
debug(RPT_DEBUG, "Section [%s] not found in LDAP.", sectionname);
380
400
ldap_msgfree(res);
381
debug( RPT_DEBUG, "Found section [%s] in LDAP", sectionname);
382
s = (section*) malloc( sizeof( section ));
383
s->name=strdup( sectionname );
385
s->next_section = NULL;
401
debug(RPT_DEBUG, "Found section [%s] in LDAP", sectionname);
402
s = (section*) malloc(sizeof(section));
404
s->name = strdup(sectionname);
406
s->next_section = NULL;
388
410
#endif /* WITH_LDAP_SUPPORT */
390
for( s=first_section; s; s=s->next_section ) {
391
if( strcasecmp( s->name, sectionname ) == 0 ) {
412
for (s = first_section; s != NULL; s = s->next_section) {
413
if (strcasecmp(s->name, sectionname) == 0) {
395
return NULL; /* not found*/
417
return NULL; /* not found */
398
section * add_section( char * sectionname )
421
static section *add_section(const char *sectionname)
401
section ** place = &first_section;
424
section **place = &first_section;
403
for( s=first_section; s; s=s->next_section )
426
for (s = first_section; s != NULL; s = s->next_section)
404
427
place = &(s->next_section);
406
*place = (section*) malloc( sizeof( section ));
407
(*place)->name = strdup( sectionname );
408
(*place)->first_key = NULL;
409
(*place)->next_section = NULL;
429
*place = (section*) malloc(sizeof(section));
430
if (*place != NULL) {
431
(*place)->name = strdup(sectionname);
432
(*place)->first_key = NULL;
433
(*place)->next_section = NULL;
414
key * find_key( section * s, char * keyname, int skip )
440
static key *find_key(section *s, const char *keyname, int skip)
418
key * last_key = NULL;
444
key *last_key = NULL;
420
446
#ifdef WITH_LDAP_SUPPORT
426
452
#endif /* WITH_LDAP_SUPPORT */
428
454
/* Check for NULL section*/
431
458
#ifdef WITH_LDAP_SUPPORT
433
debug( RPT_DEBUG, "Searching LDAP for key '%s' in section [%s] skipping %d entries.", keyname, s->name, skip);
460
debug(RPT_DEBUG, "Searching LDAP for key '%s' in section [%s] skipping %d entries.", keyname, s->name, skip);
435
462
if (NULL == (buf = malloc(BUFSIZE))){
436
report (RPT_ERR, "Could not allocate memory in find_key().");
463
report(RPT_ERR, "Could not allocate memory in find_key().");
438
465
strcpy(buf, "cn=");
439
466
strncat(buf, s->name, BUFSIZE);
440
if (LDAP_SUCCESS != (retval = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_ONELEVEL, buf, NULL, 0, &res))) {
467
if (LDAP_SUCCESS != (retval = ldap_search_s(ld, ldap_base_dn, LDAP_SCOPE_ONELEVEL, buf, NULL, 0, &res))) {
441
468
if (NULL != buf) {
445
472
ldap_msgfree(res);
446
report( RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
473
report(RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
449
if (NULL == (entry = ldap_first_entry( ld, res ))) {
450
debug( RPT_DEBUG, "Section [%s] not found in LDAP.", s->name);
476
if (NULL == (entry = ldap_first_entry(ld, res))) {
477
debug(RPT_DEBUG, "Section [%s] not found in LDAP.", s->name);
451
478
if (NULL != buf) {
455
482
/* DON'T enable the following
456
483
* ldap_msgfree(entry);
488
515
if (vals && vals[skip]) {
489
516
if (NULL != buf) {
493
520
buf=strdup(vals[skip]);
494
debug( RPT_DEBUG, "Entry found. Value is: %s", buf);
495
ldap_value_free (vals);
497
k=(key*) malloc( sizeof( key ));
498
k->name = strdup( keyname );
499
k->value = strdup( buf );
521
debug(RPT_DEBUG, "Entry found. Value is: %s", buf);
522
ldap_value_free(vals);
524
k = (key *) malloc(sizeof(key));
526
k->name = strdup(keyname);
527
k->value = strdup(buf);
502
531
if (NULL != buf) {
508
report( RPT_ERR, "LDAP server encountered errors.");
509
ldap_value_free (vals);
537
report(RPT_ERR, "LDAP server encountered errors.");
538
ldap_value_free(vals);
510
539
if (NULL != buf) {
516
545
#endif /* WITH_LDAP_SUPPORT */
518
for( k=s->first_key; k; k=k->next_key ) {
547
for (k = s->first_key; k != NULL; k = k->next_key) {
520
549
/* Did we find the right key ?*/
521
if( strcasecmp( k->name, keyname ) == 0 ) {
522
if( count == skip ) {
550
if (strcasecmp(k->name, keyname) == 0) {
561
return NULL; /* not found*/
565
static key *add_key(section *s, const char *keyname, const char *value)
569
key **place = &(s->first_key);
571
for (k = s->first_key; k != NULL; k = k->next_key)
572
place = &(k->next_key);
574
*place = (key *) malloc(sizeof(key));
575
if (*place != NULL) {
576
(*place)->name = strdup(keyname);
577
(*place)->value = strdup(value);
578
(*place)->next_key = NULL;
533
return NULL; /* not found*/
536
key * add_key( section * s, char * keyname, char * value )
540
key ** place = &( s->first_key );
542
for( k=s->first_key; k; k=k->next_key )
543
place = &(k->next_key);
545
*place = (key*) malloc( sizeof( key ));
546
(*place)->name = strdup( keyname );
547
(*place)->value = strdup( value );
548
(*place)->next_key = NULL;
553
char get_next_char_f(buffile * f) {
554
char * buf = buffile_read(f, 1);
564
#define ST_SECTIONNAME 2
567
#define ST_QUOTEDVALUE 11
568
#define ST_QUOTEDVALUE_ESCCHAR 12
569
#define ST_INVALID_SECTIONNAME 23
570
#define ST_INVALID_KEYNAME 24
571
#define ST_INVALID_VALUE 30
572
#define ST_INVALID_QUOTEDVALUE 31
576
#define MAXSECTIONNAMELENGTH 40
577
#define MAXKEYNAMELENGTH 40
578
#define MAXVALUELENGTH 200
582
int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr, buffile * f)
584
char state = ST_INITIAL;
587
static char get_next_char_f(FILE *f)
591
return((c == EOF) ? '\0' : c);
597
#define ST_COMMENT 257
598
#define ST_SECTIONLABEL 258
599
#define ST_KEYNAME 259
600
#define ST_ASSIGNMENT 260
602
#define ST_QUOTEDVALUE 262
603
#define ST_SECTIONLABEL_DONE 263
604
#define ST_VALUE_DONE 264
605
#define ST_INVALID_SECTIONLABEL 265
606
#define ST_INVALID_KEYNAME 266
607
#define ST_INVALID_ASSIGNMENT 267
608
#define ST_INVALID_VALUE 268
612
#define MAXSECTIONLABELLENGTH 40
613
#define MAXKEYNAMELENGTH 40
614
#define MAXVALUELENGTH 200
617
static int process_config(section **current_section, char(*get_next_char)(), const char *source_descr, FILE *f)
619
int state = ST_INITIAL;
586
char sectionname[MAXSECTIONNAMELENGTH+1];
621
char sectionname[MAXSECTIONLABELLENGTH+1];
587
622
int sectionname_pos = 0;
588
623
char keyname[MAXKEYNAMELENGTH+1];
589
624
int keyname_pos = 0;
590
625
char value[MAXVALUELENGTH+1];
591
626
int value_pos = 0;
596
while( state != ST_END ) {
599
ch = get_next_char(f);
602
ch = get_next_char();
605
/* Secretly keep count of the line numbers*/
632
while (state != ST_END) {
638
/* Secretly keep count of the line numbers */
622
/* It's a comment or an error*/
626
/* It's a section name*/
627
state = ST_SECTIONNAME;
659
state = ST_SECTIONLABEL;
629
660
sectionname_pos = 0;
661
sectionname[sectionname_pos] = '\0';
635
665
state = ST_KEYNAME;
651
report( RPT_WARNING, "Section name incorrectly closed on line %d of %s: %s", line_nr, source_descr, sectionname );
659
report( RPT_WARNING, "Section name contains invalid chars on line %d of %s: %s", line_nr, source_descr, sectionname );
660
state = ST_INVALID_SECTIONNAME;
667
keyname[keyname_pos++] = ch;
668
keyname[keyname_pos] = '\0';
671
case ST_SECTIONLABEL:
672
/* section label: "["{non-space chars}+"]" */
676
/* premature end of label */
677
report(RPT_WARNING, "Unterminated section label on line %d of %s: %s",
678
line_nr, source_descr, sectionname);
680
state = ST_INITIAL; /* alrady at the end, no resync required */
663
if( !( *current_section=find_section( sectionname ))) {
664
*current_section=add_section( sectionname );
683
/* label terminated: find/create section */
684
if (!(*current_section = find_section(sectionname))) {
685
*current_section = add_section(sectionname);
669
report( RPT_WARNING, "Section name incorrectly closed on line %d of %s: %s", line_nr, source_descr, sectionname );
687
state = ST_SECTIONLABEL_DONE;
692
// /* no spaces allowed in section labels WHY? */
693
// report(RPT_WARNING, "Invalid character in section label on line %d of %s: %s",
694
// line_nr, source_descr, sectionname);
696
// state = ST_INVALID_SECTIONLABEL; /* resync required */
672
if( sectionname_pos<MAXSECTIONNAMELENGTH ) {
699
/* append char to section label */
700
if (sectionname_pos < MAXSECTIONLABELLENGTH) {
673
701
sectionname[sectionname_pos++] = ch;
674
sectionname[sectionname_pos] = 0;
676
report( RPT_WARNING, "Section name too long on line %d of %s: %s", line_nr, source_descr, sectionname );
677
state = ST_INVALID_SECTIONNAME;
702
sectionname[sectionname_pos] = '\0';
681
case ST_INVALID_SECTIONNAME:
705
report(RPT_WARNING, "Section name too long on line %d of %s: %s",
706
line_nr, source_descr, sectionname);
708
state = ST_INVALID_SECTIONLABEL; /* resync required */
712
/* key name: {non-space chars}+ */
696
report( RPT_WARNING, "Loose word found on line %d of %s: %s", line_nr, source_descr, keyname );
717
/* ignore trailing spaces */
718
if (keyname_pos != 0)
719
state = ST_ASSIGNMENT;
702
report( RPT_WARNING, "Key name contains invalid characters on line %d of %s: %s", line_nr, source_descr, keyname );
703
state = ST_INVALID_KEYNAME;
723
/* premature end of line */
724
report(RPT_WARNING, "Loose word found on line %d of %s: %s",
725
line_nr, source_descr, keyname);
727
state = ST_INITIAL; /* already at the end; no resync required */
730
/* end of key reached, "=" found, now we need a value */
706
731
state = ST_VALUE;
738
// /* character invalid in key names WHY ? */
739
// report(RPT_WARNING, "Invalid character in key name on line %d of %s: %s",
740
// line_nr, source_descr, keyname);
742
// state = ST_INVALID_KEYNAME; /* resync required */
711
if( keyname_pos>=MAXKEYNAMELENGTH ) {
712
report( RPT_WARNING, "Key name too long on line %d of %s: %s", line_nr, source_descr, keyname );
713
state = ST_INVALID_KEYNAME;
745
/* append char to key name */
746
if (keyname_pos < MAXKEYNAMELENGTH) {
715
747
keyname[keyname_pos++] = ch;
716
keyname[keyname_pos] = 0;
748
keyname[keyname_pos] = '\0';
751
report(RPT_WARNING, "Key name too long on line %d of %s: %s",
752
line_nr, source_descr, keyname);
754
state = ST_INVALID_KEYNAME; /* resync required */
720
case ST_INVALID_KEYNAME:
758
/* assignement: "=" */
762
/* ignore leading spaces */
765
/* "=" found, now we need a value */
771
report(RPT_WARNING, "Assigment expected on line %d of %s: %s",
772
line_nr, source_descr, keyname);
774
state = ST_INVALID_ASSIGNMENT;
778
/* value: {non-space char}+ | "\""{any potentially-quoted char}+"\"" */
782
/* allow comment if we already had a value */
783
/* WHY ONLY THEN ? 'xx=' can be seen as equivalent to 'xx=""' */
734
report( RPT_WARNING, "Value contains invalid characters on line %d of %s, at key: %s", line_nr, source_descr, keyname );
792
/* illegal characters WHY? */
793
report(RPT_WARNING, "Invalid character '%c' in value on line %d of %s, at key: %s",
794
ch, line_nr, source_descr, keyname);
735
796
state = ST_INVALID_VALUE;
738
state = ST_QUOTEDVALUE;
800
/* ignore leading spaces */
745
/* Value complete !*/
746
if( ! *current_section ) {
747
report( RPT_WARNING, "Data before any section on line %d of %s with key: %s", line_nr, source_descr, keyname );
808
if (!*current_section) {
809
report(RPT_WARNING, "Data outside sections on line %d of %s with key: %s",
810
line_nr, source_descr, keyname);
750
814
/* Store the value*/
751
k = add_key( *current_section, keyname, value );
815
k = add_key(*current_section, keyname, value);
753
817
/* And be ready for next thing...*/
818
state = ((ch == ' ') || (ch == '\t')) ? ST_VALUE_DONE : ST_INITIAL;
822
state = ST_QUOTEDVALUE;
757
if( value_pos<MAXVALUELENGTH ) {
825
/* append char to value */
826
if (value_pos < MAXVALUELENGTH) {
758
827
value[value_pos++] = ch;
759
value[value_pos] = 0;
761
report( RPT_WARNING, "Value key is too long on line %d of %s, at key: %s", line_nr, source_descr, keyname );
762
state = ST_INVALID_KEYNAME;
828
value[value_pos] = '\0';
766
case ST_INVALID_VALUE:
772
state = ST_INVALID_QUOTEDVALUE;
831
report(RPT_WARNING, "Value too long on line %d of %s, at key: %s",
832
line_nr, source_descr, keyname);
834
state = ST_INVALID_VALUE;
775
837
case ST_QUOTEDVALUE:
838
/* a quoted part of a string */
779
report( RPT_WARNING, "String is incorrectly terminated on line %d of %s: %s", line_nr, source_descr, keyname );
842
report(RPT_WARNING, "Premature end of quoted string on line %d of %s: %s",
843
line_nr, source_descr, keyname);
780
845
state = ST_INITIAL;
789
855
state = ST_VALUE;
862
case 'a': ch = '\a'; break;
863
case 'b': ch = '\b'; break;
864
case 'f': ch = '\f'; break;
795
865
case 'n': ch = '\n'; break;
796
866
case 'r': ch = '\r'; break;
797
867
case 't': ch = '\t'; break;
798
/* default: litteral*/
868
case 'v': ch = '\v'; break;
869
/* default: literal char (i.e. ignore '\') */
802
873
value[value_pos++] = ch;
803
value[value_pos] = 0;
874
value[value_pos] = '\0';
806
case ST_INVALID_QUOTEDVALUE:
877
case ST_SECTIONLABEL_DONE:
892
/* illegal characters */
893
report(RPT_WARNING, "Invalid character '%c' on line %d of %s",
894
ch, line_nr, source_descr);
812
896
state = ST_INVALID_VALUE;
898
case ST_INVALID_SECTIONLABEL:
899
/* invalid section label: resync up to end of label/next line */
903
case ST_INVALID_ASSIGNMENT:
904
case ST_INVALID_KEYNAME:
905
case ST_INVALID_VALUE:
907
/* comment or error: ignore anything up to the next line */
912
if ((!error) && (state != ST_INITIAL) && (state != ST_COMMENT) &&
913
(state != ST_SECTIONLABEL_DONE) && (state != ST_VALUE_DONE)) {
914
report(RPT_WARNING, "Premature end of configuration on line %d of %s: %d",
915
line_nr, source_descr, state);
923
return (error) ? -1 : 0;
927
#if CONFIGFILE_DEBUGTEST
928
void config_dump(void)
932
for (s = first_section; s != NULL; s = s->next_section) {
935
fprintf(stderr, "[%s]\n", s->name);
937
for (k = s->first_key; k != NULL; k = k->next_key)
938
fprintf(stderr, "%s = \"%s\"\n", k->name, k->value);
940
fprintf(stderr, "\n");
945
int main(int argc, char *argv[])
948
config_read_file(argv[1]);