/***************************************************************** ** loadconfig (file, conf) ** Loads a config file into the "conf" structure pointed to by "z". ** If "z" is NULL then a new conf struct will be dynamically ** allocated. ** If no filename is given the conf struct will be initialized ** by the builtin default config *****************************************************************/ zconf_t *loadconfig (const char *filename, zconf_t *z) { FILE *fp; char buf[1023+1]; unsigned int line; if ( z == NULL ) /* allocate new memory for zconf_t */ { if ( (z = calloc (1, sizeof (zconf_t))) == NULL ) return NULL; if ( filename && *filename ) memcpy (z, &def, sizeof (zconf_t)); /* init new struct with defaults */ } if ( filename == NULL || *filename == '\0' ) /* no file name given... */ { dbg_val0("loadconfig (NULL)\n"); memcpy (z, &def, sizeof (zconf_t)); /* ..then init with defaults */ return z; } dbg_val1 ("loadconfig (%s)\n", filename); set_all_varptr (z); if ( (fp = fopen(filename, "r")) == NULL ) fatal ("Could not open config file \"%s\"\n", filename); line = 0; while (fgets(buf, sizeof(buf), fp)) parseconfigline (buf, ++line, z); fclose(fp); return z; }
/***************************************************************** ** lg_str2syslog (facility_name) *****************************************************************/ int lg_str2syslog (const char *facility) { lg_symtbl_t *p; dbg_val1 ("lg_str2syslog (%s)\n", facility); if ( !facility ) return LG_NONE; for ( p = symtbl; p->str; p++ ) if ( strcasecmp (facility, p->str) == 0 ) return p->syslog_level; return LG_NONE; }
zconf_t *loadconfig_fromstr (const char *str, zconf_t *z) { char *buf; char *tok, *toksave; unsigned int line; if ( z == NULL ) { if ( (z = calloc (1, sizeof (zconf_t))) == NULL ) return NULL; memcpy (z, &def, sizeof (zconf_t)); /* init with defaults */ } if ( str == NULL || *str == '\0' ) { dbg_val0("loadconfig_fromstr (NULL)\n"); memcpy (z, &def, sizeof (zconf_t)); /* init with defaults */ return z; } dbg_val1 ("loadconfig_fromstr (\"%s\")\n", str); set_all_varptr (z); /* str is const, so we have to copy it into a new buffer */ if ( (buf = strdup (str)) == NULL ) fatal ("loadconfig_fromstr: Out of memory"); line = 0; tok = strtok_r (buf, STRCONFIG_DELIMITER, &toksave); while ( tok ) { line++; parseconfigline (tok, line, z); tok = strtok_r (NULL, STRCONFIG_DELIMITER, &toksave); } free (buf); return z; }
static void parseconfigline (char *buf, unsigned int line, zconf_t *z) { char *end, *val, *p; char *tag; unsigned int len, found; zconf_para_t *c; assert (buf[0] != '\0'); p = &buf[strlen(buf)-1]; /* Chop off white space at eol */ while ( p >= buf && isspace (*p) ) *p-- = '\0'; for (p = buf; isspace (*p); p++ ) /* Ignore leading white space */ ; /* Ignore comments and emtpy lines */ if ( *p == '\0' || ISCOMMENT (p) ) return; tag = p; /* Get the end of the first argument */ end = &buf[strlen(buf)-1]; while ( p < end && !ISDELIM (*p) ) /* Skip until delim */ p++; *p++ = '\0'; /* Terminate this argument */ dbg_val1 ("Parsing \"%s\"\n", tag); while ( p < end && ISDELIM (*p) ) /* Skip delim chars */ p++; val = p; /* Start of the value */ dbg_val1 ("\tgot value \"%s\"\n", val); /* If starting with quote, skip until next quote */ if ( *p == '"' || *p == '\'' ) { p++; /* Find next quote */ while ( p <= end && *p && *p != *val ) p++; *p = '\0'; val++; /* Skip the first quote */ } else /* Otherwise check if there is any comment char at the end */ { while ( p < end && *p && !ISCOMMENT(p) ) p++; if ( ISCOMMENT (p) ) { do /* Chop off white space before comment */ *p-- = '\0'; while ( p >= val && isspace (*p) ); } } /* Otherwise it is already terminated above */ found = 0; c = confpara; while ( !found && c->type != CONF_END ) { len = strlen (c->label); if ( strcasecmp (tag, c->label) == 0 ) { char **str; char quantity; long lval; found = 1; switch ( c->type ) { case CONF_LEVEL: case CONF_FACILITY: case CONF_STRING: str = (char **)c->var; *str = strdup (val); str_untaint (*str); /* remove "bad" characters */ break; case CONF_INT: sscanf (val, "%d", (int *)c->var); break; case CONF_TIMEINT: quantity = 'd'; sscanf (val, "%ld%c", &lval, &quantity); if ( quantity == 'm' ) lval *= MINSEC; else if ( quantity == 'h' ) lval *= HOURSEC; else if ( quantity == 'd' ) lval *= DAYSEC; else if ( quantity == 'w' ) lval *= WEEKSEC; else if ( quantity == 'y' ) lval *= YEARSEC; (*(long *)c->var) = lval; break; case CONF_ALGO: if ( strcasecmp (val, "rsa") == 0 || strcasecmp (val, "rsamd5") == 0 ) *((int *)c->var) = DK_ALGO_RSA; else if ( strcasecmp (val, "dsa") == 0 ) *((int *)c->var) = DK_ALGO_DSA; else if ( strcasecmp (val, "rsasha1") == 0 ) *((int *)c->var) = DK_ALGO_RSASHA1; else if ( strcasecmp (val, "nsec3dsa") == 0 || strcasecmp (val, "n3dsa") == 0 ) *((int *)c->var) = DK_ALGO_NSEC3DSA; else if ( strcasecmp (val, "nsec3rsasha1") == 0 || strcasecmp (val, "n3rsasha1") == 0 ) *((int *)c->var) = DK_ALGO_NSEC3RSASHA1; else error ("Illegal algorithm \"%s\" " "in line %d.\n" , val, line); break; case CONF_SERIAL: if ( strcasecmp (val, "unixtime") == 0 ) *((serial_form_t *)c->var) = Unixtime; else if ( strcasecmp (val, "incremental") == 0 ) *((serial_form_t *)c->var) = Incremental; else error ("Illegal serial no format \"%s\" " "in line %d.\n" , val, line); break; case CONF_BOOL: *((int *)c->var) = ISTRUE (val); break; default: fatal ("Illegal configuration type in line %d.\n", line); } } c++; } if ( !found ) error ("Unknown configuration statement: %s \"%s\"\n", tag, val); return; }