1 #include <stdio.h>
2 #include <dotconf.h>
3 #include "ganglia_priv.h"
4 #include "g25_config.h"
5 
6 gmond_config_t gmond_config;
7 
8 static char *
conf_strdup(const char * s)9 conf_strdup (const char *s)
10 {
11   char *result = (char*)malloc(strlen(s) + 1);
12   if (result == (char*)0)
13     return (char*)0;
14   strcpy(result, s);
15   return result;
16 }
17 
FUNC_ERRORHANDLER(errorhandler)18 static FUNC_ERRORHANDLER(errorhandler)
19 {
20    printf("gmond config file error: %s\n", msg);
21    exit(EXIT_FAILURE);
22 }
23 
DOTCONF_CB(cb_name)24 static DOTCONF_CB(cb_name)
25 {
26    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
27    free(c->name);
28    c->name = conf_strdup(cmd->data.str);
29    return NULL;
30 }
31 
DOTCONF_CB(cb_owner)32 static DOTCONF_CB(cb_owner)
33 {
34    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
35    free(c->owner);
36    c->owner = conf_strdup(cmd->data.str);
37    return NULL;
38 }
39 
DOTCONF_CB(cb_latlong)40 static DOTCONF_CB(cb_latlong)
41 {
42    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
43    free(c->latlong);
44    c->latlong = conf_strdup(cmd->data.str);
45    return NULL;
46 }
47 
DOTCONF_CB(cb_location)48 static DOTCONF_CB(cb_location)
49 {
50    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
51    free(c->location);
52    c->location = conf_strdup(cmd->data.str);
53    return NULL;
54 }
55 
DOTCONF_CB(cb_url)56 static DOTCONF_CB(cb_url)
57 {
58    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
59    free(c->url);
60    c->url = conf_strdup(cmd->data.str);
61    return NULL;
62 }
63 
DOTCONF_CB(cb_mcast_channel)64 static DOTCONF_CB(cb_mcast_channel)
65 {
66    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
67    free(c->mcast_channel);
68    c->mcast_channel = conf_strdup(cmd->data.str);
69    return NULL;
70 }
71 
DOTCONF_CB(cb_mcast_port)72 static DOTCONF_CB(cb_mcast_port)
73 {
74    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
75    c->mcast_port = cmd->data.value;
76    return NULL;
77 }
78 
DOTCONF_CB(cb_mcast_if)79 static DOTCONF_CB(cb_mcast_if)
80 {
81    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
82    /* no free.. set to NULL by default */
83    c->mcast_if_given = 1;
84    c->mcast_if = conf_strdup(cmd->data.str);
85    return NULL;
86 }
87 
DOTCONF_CB(cb_mcast_ttl)88 static DOTCONF_CB(cb_mcast_ttl)
89 {
90    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
91    c->mcast_ttl  = cmd->data.value;
92    return NULL;
93 }
94 
DOTCONF_CB(cb_mcast_threads)95 static DOTCONF_CB(cb_mcast_threads)
96 {
97    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
98    c->mcast_threads = cmd->data.value;
99    return NULL;
100 }
101 
DOTCONF_CB(cb_xml_port)102 static DOTCONF_CB(cb_xml_port)
103 {
104    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
105    c->xml_port = cmd->data.value;
106    return NULL;
107 }
108 
DOTCONF_CB(cb_xml_threads)109 static DOTCONF_CB(cb_xml_threads)
110 {
111    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
112    c->xml_threads = cmd->data.value;
113    return NULL;
114 }
115 
DOTCONF_CB(cb_trusted_hosts)116 static DOTCONF_CB(cb_trusted_hosts)
117 {
118    int i;
119    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
120 
121    c->trusted_hosts = (char **)malloc(sizeof(char *) * cmd->arg_count + 1);
122    if(!c->trusted_hosts)
123      {
124        fprintf(stderr,"Unable to create trusted_hosts array. Exiting.\n");
125        exit(EXIT_FAILURE);
126      }
127 
128    for (i = 0; i < cmd->arg_count; i++)
129       {
130          c->trusted_hosts[i] = strdup(cmd->data.list[i]);
131       }
132    c->trusted_hosts[i] = NULL;
133    return NULL;
134 }
135 
DOTCONF_CB(cb_num_nodes)136 static DOTCONF_CB(cb_num_nodes)
137 {
138    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
139    c->num_nodes = cmd->data.value;
140    return NULL;
141 }
142 
DOTCONF_CB(cb_num_custom_metrics)143 static DOTCONF_CB(cb_num_custom_metrics)
144 {
145    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
146    c->num_custom_metrics = cmd->data.value;
147    return NULL;
148 }
149 
DOTCONF_CB(cb_mute)150 static DOTCONF_CB(cb_mute)
151 {
152    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
153    c->mute = cmd->data.value;
154    return NULL;
155 }
156 
DOTCONF_CB(cb_deaf)157 static DOTCONF_CB(cb_deaf)
158 {
159    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
160    c->deaf = cmd->data.value;
161    return NULL;
162 }
163 
DOTCONF_CB(cb_allow_extra_data)164 static DOTCONF_CB(cb_allow_extra_data)
165 {
166    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
167    c->allow_extra_data = cmd->data.value;
168    return NULL;
169 }
170 
DOTCONF_CB(cb_debug_level)171 static DOTCONF_CB(cb_debug_level)
172 {
173    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
174    c->debug_level = cmd->data.value;
175    return NULL;
176 }
177 
DOTCONF_CB(cb_no_setuid)178 static DOTCONF_CB(cb_no_setuid)
179 {
180    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
181    c->no_setuid = cmd->data.value;
182    return NULL;
183 }
184 
DOTCONF_CB(cb_setuid)185 static DOTCONF_CB(cb_setuid)
186 {
187    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
188    c->setuid = conf_strdup( cmd->data.str );
189    return NULL;
190 }
191 
DOTCONF_CB(cb_no_gexec)192 static DOTCONF_CB(cb_no_gexec)
193 {
194    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
195    c->no_gexec = cmd->data.value;
196    return NULL;
197 }
198 
DOTCONF_CB(cb_all_trusted)199 static DOTCONF_CB(cb_all_trusted)
200 {
201    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
202    c->all_trusted = cmd->data.value;
203    return NULL;
204 }
205 
DOTCONF_CB(cb_host_dmax)206 static DOTCONF_CB(cb_host_dmax)
207 {
208    gmond_config_t *c = (gmond_config_t *)cmd->option->info;
209    c->host_dmax = cmd->data.value;
210    return NULL;
211 }
212 
213 
214 static int
set_defaults(gmond_config_t * config)215 set_defaults(gmond_config_t *config )
216 {
217    /* Gmond defaults */
218    config->name = conf_strdup("unspecified");
219    config->owner = conf_strdup("unspecified");
220    config->latlong = conf_strdup("unspecified");
221    config->url = conf_strdup("unspecified");
222    config->location = conf_strdup("unspecified");
223    config->mcast_channel = conf_strdup("239.2.11.71");
224    config->mcast_port = 8649;
225    config->mcast_if_given = 0;
226    config->mcast_ttl = 1;
227    config->mcast_threads = 2;
228    config->xml_port = 8649;
229    config->xml_threads = 2;
230    config->trusted_hosts = NULL;
231    config->num_nodes = 1024;
232    config->num_custom_metrics = 16;
233    config->mute = 0;
234    config->deaf = 0;
235    config->allow_extra_data = 1;
236    config->debug_level = 0;
237    config->no_setuid = NO_SETUID;
238    config->setuid = conf_strdup(SETUID_USER);
239    config->no_gexec = 0;
240    config->all_trusted = 0;
241    config->host_dmax = 0;
242 
243    return 0;
244 }
245 
246 static int
print_config(char * path,gmond_config_t * config)247 print_config(char *path, gmond_config_t *config)
248 {
249   int i;
250   char *p;
251 
252   fprintf(stdout,"/* global variables */\n");
253   fprintf(stdout,"globals {\n  mute = \"%s\"\n  deaf = \"%s\"\n  allow_extra_data = \"%s\"\n  debug_level = \"%ld\"\n  setuid = \"%s\"\n  user=\"%s\"\n  gexec = \"%s\"\n  host_dmax = \"%ld\"\n}\n\n",
254           config->mute? "yes":"no",
255           config->deaf? "yes":"no",
256           config->allow_extra_data? "yes":"no",
257           config->debug_level,
258           config->no_setuid? "no":"yes",
259           config->setuid,
260           config->no_gexec? "no":"yes",
261           config->host_dmax);
262 
263   fprintf(stdout,"/* info about cluster  */\n");
264   fprintf(stdout,"cluster {\n  name = \"%s\"\n  owner = \"%s\"\n  latlong = \"%s\"\n  url=\"%s\"\n}\n\n",
265           config->name, config->owner, config->latlong, config->url);
266 
267   fprintf(stdout,"/* info about host */\n");
268   fprintf(stdout,"host {\n  location = \"%s\"\n}\n\n",
269           config->location);
270 
271   fprintf(stdout,"/* channel to send multicast on mcast_channel:mcast_port */\n");
272   fprintf(stdout,"udp_send_channel {\n  mcast_join = \"%s\"\n  port = \"%hd\"\n  ttl=\"%ld\"\n",
273           config->mcast_channel, config->mcast_port, config->mcast_ttl);
274   if(config->mcast_if_given)
275     {
276       fprintf(stdout,"  mcast_if = \"%s\"\n", config->mcast_if);
277     }
278   fprintf(stdout,"}\n\n");
279 
280   fprintf(stdout,"/* channel to receive multicast from mcast_channel:mcast_port */\n");
281   fprintf(stdout,"udp_recv_channel {\n  mcast_join = \"%s\"\n  port = \"%hd\"\n  bind = \"%s\"\n",
282           config->mcast_channel, config->mcast_port, config->mcast_channel);
283   if(config->mcast_if_given)
284     {
285       fprintf(stdout,"  mcast_if = \"%s\"\n", config->mcast_if);
286     }
287   fprintf(stdout,"}\n\n");
288 
289   fprintf(stdout,"/* channel to export xml on xml_port */\n");
290   fprintf(stdout,"tcp_accept_channel {\n  port = \"%hd\"\n", config->xml_port);
291   if( config->trusted_hosts  && !config->all_trusted )
292     {
293       fprintf(stdout,"/* your trusted_hosts assuming ipv4 mask*/\n");
294       fprintf(stdout,"  acl {\n    default=\"deny\"\n");
295       for(i = 0, p = config->trusted_hosts[i]; p; i++, p = config->trusted_hosts[i])
296         {
297           fprintf(stdout, "    access {\n");
298           fprintf(stdout, "      ip=\"%s\"\n      mask = 32\n      action = \"allow\"\n", p);
299           fprintf(stdout, "    }\n");
300         }
301       fprintf(stdout, "    access {\n");
302       fprintf(stdout, "      ip=\"127.0.0.1\"\n      mask = 32\n      action = \"allow\"\n");
303       fprintf(stdout, "    }\n");
304       fprintf(stdout,"  }\n");/* close acl */
305     }
306   fprintf(stdout,"}\n\n"); /* close tcp_accept_channel */
307   fprintf(stdout,"%s\n", Ganglia_default_collection_groups());
308   return 0;
309 }
310 
311 
312 int
print_ganglia_25_config(char * path)313 print_ganglia_25_config( char *path )
314 {
315    configfile_t *configfile;
316    FILE *fp;
317    static configoption_t gmond_options[] =
318       {
319          {"name", ARG_STR, cb_name, &gmond_config, 0},
320          {"owner", ARG_STR, cb_owner, &gmond_config, 0},
321          {"latlong", ARG_STR, cb_latlong, &gmond_config, 0},
322          {"url", ARG_STR, cb_url, &gmond_config, 0},
323          {"location", ARG_STR, cb_location, &gmond_config, 0},
324          {"mcast_channel", ARG_STR, cb_mcast_channel, &gmond_config, 0},
325          {"mcast_port", ARG_INT, cb_mcast_port, &gmond_config, 0},
326          {"mcast_if", ARG_STR, cb_mcast_if, &gmond_config, 0},
327          {"mcast_ttl", ARG_INT, cb_mcast_ttl, &gmond_config, 0},
328          {"mcast_threads", ARG_INT, cb_mcast_threads, &gmond_config, 0},
329          {"xml_port", ARG_INT, cb_xml_port, &gmond_config, 0},
330          {"xml_threads", ARG_INT, cb_xml_threads, &gmond_config, 0},
331          {"trusted_hosts", ARG_LIST, cb_trusted_hosts, &gmond_config, 0},
332          {"num_nodes", ARG_INT, cb_num_nodes, &gmond_config, 0},
333          {"num_custom_metrics", ARG_INT, cb_num_custom_metrics, &gmond_config, 0},
334          {"mute", ARG_TOGGLE, cb_mute, &gmond_config, 0},
335          {"deaf", ARG_TOGGLE, cb_deaf, &gmond_config, 0},
336          {"allow_extra_data", ARG_TOGGLE, cb_allow_extra_data, &gmond_config, 0},
337          {"debug_level", ARG_INT, cb_debug_level, &gmond_config, 0},
338          {"no_setuid", ARG_TOGGLE, cb_no_setuid, &gmond_config, 0},
339          {"setuid", ARG_STR, cb_setuid, &gmond_config, 0},
340          {"no_gexec", ARG_TOGGLE, cb_no_gexec, &gmond_config, 0},
341          {"all_trusted", ARG_TOGGLE, cb_all_trusted, &gmond_config, 0},
342          {"host_dmax", ARG_INT, cb_host_dmax, &gmond_config, 0},
343          LAST_OPTION
344       };
345 
346    if(!path)
347      {
348        return 1;
349      }
350    fp = fopen( path, "r");
351    if(!fp)
352      {
353        fprintf(stderr,"Unable to open ganglia 2.5 configuration '%s'. Exiting.\n", path);
354        return 1;
355      }
356 
357    set_defaults(&gmond_config);
358 
359    configfile = dotconf_create(path, gmond_options, 0, CASE_INSENSITIVE);
360    if(!configfile)
361      {
362        fprintf(stderr,"dotconf_create() error for configuration '%s'. Exiting.\n", path);
363        return 1;
364      }
365 
366    configfile->errorhandler = (dotconf_errorhandler_t) errorhandler;
367 
368    if (dotconf_command_loop(configfile) == 0)
369       {
370          dotconf_cleanup(configfile);
371          return 1;
372       }
373    dotconf_cleanup(configfile);
374 
375    print_config(path, &gmond_config);
376    return 0;
377 }
378