d08b2601b93565bdcd23856b6f244d29ea32a709
[public/pyceo-broken.git] / src / config.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <limits.h>
4
5 #include "config.h"
6 #include "parser.h"
7 #include "util.h"
8
9 #define DEF_STR NULL
10 #define DEF_INT LONG_MIN
11
12 #define CONFIG_STR(x) char *x = DEF_STR;
13 #define CONFIG_INT(x) long  x = DEF_INT;
14 #include "config-vars.h"
15 #undef CONFIG_STR
16 #undef CONFIG_INT
17
18 struct config_var {
19     const char *name;
20     void *p;
21     enum { CONFIG_TYPE_STR, CONFIG_TYPE_INT } type;
22 };
23
24 #define CONFIG_STR(x) {#x, &x, CONFIG_TYPE_STR },
25 #define CONFIG_INT(x) {#x, &x, CONFIG_TYPE_INT },
26 static struct config_var config_vars[] = {
27 #include "config-vars.h"
28 };
29 #undef CONFIG_STR
30 #undef CONFIG_INT
31
32 const char *default_config_dir = "/etc/csc";
33 const char *config_filename = "accounts.cf";
34 const char *config_dir;
35
36 void config_var(char *var, char *val) {
37     int i;
38
39     for (i = 0; i < sizeof(config_vars)/sizeof(*config_vars); i++) {
40         if (!strcmp(var, config_vars[i].name)) {
41             switch (config_vars[i].type) {
42                 case CONFIG_TYPE_STR:
43                     if (*(char **)config_vars[i].p)
44                         free(*(char **)config_vars[i].p);
45                     *(char **)config_vars[i].p = xstrdup(val);
46                     break;
47                 case CONFIG_TYPE_INT:
48                     *(long *)config_vars[i].p = config_long(var, val);
49                     break;
50                 default:
51                     fatal("unknown config var type %d", config_vars[i].type);
52             }
53         }
54     }
55 }
56
57 void configure() {
58     int i;
59     char conffile[1024];
60
61     config_dir = getenv("CEO_CONFIG_DIR") ?: default_config_dir;
62
63     if (snprintf(conffile, sizeof(conffile), "%s/%s", config_dir, config_filename) >= sizeof(conffile))
64         fatal("huge config path");
65
66     config_parse(conffile);
67
68     for (i = 0; i < sizeof(config_vars)/sizeof(*config_vars); i++) {
69         switch (config_vars[i].type) {
70             case CONFIG_TYPE_STR:
71                 if (*(char **)config_vars[i].p == DEF_STR)
72                     badconf("undefined string variable: %s", config_vars[i].name);
73                 break;
74             case CONFIG_TYPE_INT:
75                 if (*(long *)config_vars[i].p == DEF_INT)
76                     badconf("undefined integer variable: %s", config_vars[i].name);
77                 break;
78             default:
79                 fatal("unknown config var type %d", config_vars[i].type);
80         }
81     }
82 }