+int read_config_file(avl_tree_t * config_tree, const char *fname)
+{
+ int err = -2; /* Parse error */
+ FILE *fp;
+ char *buffer, *line;
+ char *variable, *value;
+ int lineno = 0, ignore = 0;
+ config_t *cfg;
+ size_t bufsize;
+
+ cp();
+
+ fp = fopen(fname, "r");
+
+ if(!fp) {
+ syslog(LOG_ERR, _("Cannot open config file %s: %s"), fname,
+ strerror(errno));
+ return -3;
+ }
+
+ bufsize = 100;
+ buffer = xmalloc(bufsize);
+
+ for(;;) {
+ line = readline(fp, &buffer, &bufsize);
+
+ if(!line) {
+ err = -1;
+ break;
+ }
+
+ if(feof(fp)) {
+ err = 0;
+ break;
+ }
+
+ lineno++;
+
+ variable = strtok(line, "\t =");
+
+ if(!variable)
+ continue; /* no tokens on this line */
+
+ if(variable[0] == '#')
+ continue; /* comment: ignore */
+
+ if(!strcmp(variable, "-----BEGIN"))
+ ignore = 1;
+
+ if(!ignore) {
+ value = strtok(NULL, "\t\n\r =");
+
+ if(!value || value[0] == '#') {
+ syslog(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
+ variable, lineno, fname);
+ break;
+ }
+
+ cfg = new_config();
+ cfg->variable = xstrdup(variable);
+ cfg->value = xstrdup(value);
+ cfg->file = xstrdup(fname);
+ cfg->line = lineno;
+
+ config_add(config_tree, cfg);
+ }
+
+ if(!strcmp(variable, "-----END"))
+ ignore = 0;
+ }
+
+ free(buffer);
+ fclose(fp);
+
+ return err;
+}
+
+int read_server_config()
+{
+ char *fname;
+ int x;
+
+ cp();
+
+ asprintf(&fname, "%s/tinc.conf", confbase);
+ x = read_config_file(config_tree, fname);
+
+ if(x == -1) { /* System error: complain */
+ syslog(LOG_ERR, _("Failed to read `%s': %s"), fname, strerror(errno));
+ }
+
+ free(fname);
+
+ return x;
+}
+
+int isadir(const char *f)