cc43d8ccc7603137b8aecbecde8797b0dcb3010c
[rahunas] / src / rh-config.c
1 /**
2  * RahuNAS configuration
3  * Author: Suriya Soutmun <darksolar@gmail.com>
4  * Date:   2008-11-26
5  */
6 #include <ctype.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <syslog.h>
10 #include <dirent.h>
11 #include <errno.h>
12
13 #include "rahunasd.h"
14 #include "rh-config.h"
15
16 enum lcfg_status rahunas_visitor(const char *key, void *data, size_t size, 
17                                  void *user_data) {
18   char *value = strndup(data, size);
19   union rahunas_config *config = (union rahunas_config *)user_data;
20   char *clone_key = NULL;
21   char *sep = NULL; 
22   char *main_key = NULL;
23   char *sub_key = NULL;
24   enum config_type cfg_type;
25
26   if(config == NULL)
27     return lcfg_status_error;
28
29   if(value == NULL)
30     return lcfg_status_error;
31
32   clone_key = strdup(key);
33   if (clone_key == NULL)
34     return lcfg_status_error;
35
36   sep = strstr(clone_key, ".");
37   main_key = clone_key;
38   sub_key = sep + 1;
39   *sep = '\0';
40
41   if (strncmp(main_key, "main", 4) == 0) {
42     cfg_type = MAIN;
43   } else {
44     cfg_type = VSERVER;
45     if (config->rh_vserver.vserver_name == NULL)
46       config->rh_vserver.vserver_name = strdup(main_key);
47   }
48
49   switch (cfg_type) {
50     case MAIN:
51       if (strncmp(sub_key, "conf_dir", 8) == 0) {
52         if (config->rh_main.conf_dir != NULL)
53           free(config->rh_main.conf_dir);
54         config->rh_main.conf_dir = strdup(value);
55       } else if (strncmp(sub_key, "bandwidth_shape", 15) == 0) {
56         if (strncmp(value, "yes", 3) == 0)
57           config->rh_main.bandwidth_shape = 1; 
58         else
59           config->rh_main.bandwidth_shape = 0;
60       } else if (strncmp(sub_key, "polling_interval", 16) == 0) {
61         config->rh_main.polling_interval = atoi(value);
62       } else if (strncmp(sub_key, "log_file", 8) == 0) {
63         if (config->rh_main.log_file != NULL)
64           free(config->rh_main.log_file);
65         config->rh_main.log_file = strdup(value); 
66       }
67       break;
68
69     case VSERVER:
70       if (strncmp(sub_key, "vserver_id", 10) == 0) {
71         config->rh_vserver.vserver_id = atoi(value);
72       } else if (strncmp(sub_key, "vserver_ip", 10) == 0) {
73         if (config->rh_vserver.vserver_ip != NULL)
74           free(config->rh_vserver.vserver_ip);
75         config->rh_vserver.vserver_ip = strdup(value); 
76       } else if (strncmp(sub_key, "idle_timeout", 12) == 0) {
77         config->rh_vserver.idle_timeout = atoi(value);
78       }
79       break;
80   }
81
82   
83   rh_free(&clone_key);
84
85   return lcfg_status_ok;
86 }
87
88 int get_config(const char *cfg_file, union rahunas_config *config) {
89   lcfg_visitor_function visitor_func = rahunas_visitor;
90   struct lcfg *c = lcfg_new(cfg_file);
91   
92   syslog(LOG_INFO, "Parsing config file: %s", cfg_file);
93
94   if (lcfg_parse(c) != lcfg_status_ok) {
95     syslog(LOG_ERR, "config error: %s", lcfg_error_get(c));
96     lcfg_delete(c);
97     return -1;
98   }
99
100   syslog(LOG_INFO, "Processing config file: %s", cfg_file);
101   if (lcfg_accept(c, visitor_func, config) != lcfg_status_ok) {
102     syslog(LOG_ERR, "config error: %s", lcfg_error_get(c));
103     lcfg_delete(c);
104     return -1;
105   }
106
107   lcfg_delete(c);
108
109   return 0;
110 }
111
112
113 int get_value(const char *cfg_file, const char *key, void **data, size_t *len)
114 {
115   lcfg_visitor_function visitor_func = rahunas_visitor;
116   struct lcfg *c = lcfg_new(cfg_file);
117   
118   if (lcfg_parse(c) != lcfg_status_ok) {
119     syslog(LOG_ERR, "config error: %s", lcfg_error_get(c));
120     lcfg_delete(c);
121     return -1;
122   }
123
124   if (lcfg_value_get(c, key, data, len) != lcfg_status_ok) {
125     lcfg_delete(c);
126     return -1;
127   } 
128
129   lcfg_delete(c);
130
131   return 0;
132 }
133
134 int get_vservers_config(const char *conf_dir, struct main_server *server)
135 {
136   DIR *dp;
137   struct dirent *dirp;
138   void *data = NULL;
139   size_t len;
140   char conf_file[200];
141
142   if ((dp = opendir(conf_dir)) == NULL)
143     return errno;
144   
145   while ((dirp = readdir(dp)) != NULL) {
146     if (strstr(dirp->d_name, ".conf") == NULL)
147       continue;
148
149     memset(conf_file, 0, sizeof(conf_file));
150
151     strncat(conf_file, conf_dir, sizeof(conf_file));
152     strncat(conf_file, "/", 1);
153     strncat(conf_file, dirp->d_name, sizeof(conf_file));
154
155     syslog(LOG_INFO, "Loading config file: %s", conf_file);
156     
157     register_vserver(server, conf_file);
158   }
159   
160   closedir(dp);
161   return 0;
162 }
163
164
165 int cleanup_vserver_config(struct rahunas_vserver_config *config)
166 {
167   rh_free(&(config->vserver_ip));
168   rh_free(&(config->vserver_name));  
169   return 0;
170 }
171
172 int cleanup_mainserver_config(struct rahunas_main_config *config)
173 {
174   rh_free(&(config->conf_dir));  
175   rh_free(&(config->log_file));
176   return 0;
177 }