~ubuntu-branches/debian/sid/apt-dater/sid

« back to all changes in this revision

Viewing changes to src/keyfiles.c

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2015-01-19 19:14:15 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20150119191415-o5emoeio9lknv8h8
Tags: 1.0.1+git20150119-1
* New upstream git snapshot.
  - Fixes FTBFS with ld -b.
    Closes: #767594

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
# include "config.h"
33
33
#endif
34
34
 
35
 
#include <libconfig.h>
36
 
 
37
 
#ifdef __linux
38
 
EXTLD(apt_dater_config);
39
 
EXTLD(hosts_config);
40
 
EXTLD(screenrc);
41
 
#endif
42
 
 
43
 
#ifdef __linux
44
 
#define DUMP_CONFIG(fn, bin)                                            \
45
 
  pathtofile = g_strdup_printf("%s/%s", cfgdir, (fn));                  \
46
 
  if(!pathtofile) g_error(_("Out of memory."));                         \
47
 
  if(g_file_test(pathtofile, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS) == FALSE) { \
48
 
    FILE *fp = NULL;                                                    \
49
 
    fp = fopen(pathtofile, "wx");                                       \
50
 
    g_message(_("Creating default config file %s"), pathtofile);        \
51
 
    if(fp) {                                                            \
52
 
      if(fwrite(LDVAR(bin), LDLEN(bin), 1, fp) != 1) g_error(_("Could not write to file %s."), pathtofile); \
53
 
      fclose(fp);                                                       \
54
 
    }                                                                   \
55
 
  }                                                                     \
56
 
  g_free(pathtofile); 
57
 
#else
58
 
#define DUMP_CONFIG(fn, bin)                                            \
59
 
  pathtofile = g_strdup_printf("%s/%s", cfgdir, (fn));                  \
60
 
  if(!pathtofile) g_error(_("Out of memory."));                         \
61
 
  if(g_file_test(pathtofile, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS) == FALSE) \
62
 
    g_error(_("Mandatory config file %s does not exist!"), pathtofile)
63
 
#endif
 
35
#include <libxml/parser.h>
 
36
#include <libxml/xpath.h>
 
37
 
 
38
#include "../conf/apt-dater.xml.inc"
 
39
#include "../conf/hosts.xml.inc"
 
40
#include "../conf/screenrc.inc"
 
41
 
 
42
void dump_config(const gchar *dir, const gchar *fn, const gchar *str, const unsigned int len) {
 
43
  gchar *pathtofile = g_strdup_printf("%s/%s", dir, (fn));
 
44
 
 
45
  if(!pathtofile)
 
46
    g_error(_("Out of memory."));
 
47
 
 
48
  if(g_file_test(pathtofile, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS) == FALSE) {
 
49
    FILE *fp = fopen(pathtofile, "wx");
 
50
    g_message(_("Creating default config file %s"), pathtofile);
 
51
    if(fp) {
 
52
      if(fwrite(str, len, 1, fp) != 1) {
 
53
        g_printerr(_("Could not write to file %s."), pathtofile);
 
54
        exit(1);
 
55
      }
 
56
      fclose(fp);
 
57
    }
 
58
  }
 
59
  g_free(pathtofile);
 
60
}
64
61
 
65
62
int chkForInitialConfig(const gchar *cfgdir, const gchar *cfgfile) {
66
63
  if(g_file_test(cfgdir, G_FILE_TEST_IS_DIR) == FALSE) {
67
64
    if(g_mkdir_with_parents (cfgdir, 0700)) return(1);
68
65
  }
69
 
  
70
 
  gchar *pathtofile;
71
 
  DUMP_CONFIG("apt-dater.config", apt_dater_config);
72
 
  DUMP_CONFIG("hosts.config", hosts_config);
73
 
  DUMP_CONFIG("screenrc", screenrc);
 
66
 
 
67
  dump_config(cfgdir, "apt-dater.xml", (gchar *)apt_dater_xml, apt_dater_xml_len);
 
68
  dump_config(cfgdir, "hosts.xml", (gchar *)hosts_xml, hosts_xml_len);
 
69
  dump_config(cfgdir, "screenrc", (gchar *)screenrc, screenrc_len);
74
70
 
75
71
 return(0);
76
72
}
98
94
    lcfg->_type = T_CFGFILE;
99
95
#endif
100
96
 
101
 
    lcfg->hostsfile = g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "hosts.conf");
 
97
    lcfg->hostsfile = g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "hosts.xml");
102
98
    lcfg->statsdir = g_strdup_printf("%s/%s/%s", g_get_user_cache_dir(), PROG_NAME, "stats");
103
99
 
104
100
    lcfg->screenrcfile = g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "screenrc");
133
129
    return lcfg;
134
130
}
135
131
 
136
 
#define CFG_GET_BOOL_DEFAULT(setting,key,var,def) \
137
 
    var = (def); \
138
 
    if((setting)) \
139
 
        config_setting_lookup_bool((setting), (key), &(var));
140
 
#define CFG_GET_STRING_DEFAULT(setting,key,var,def) \
141
 
    var = (def); \
142
 
    if((setting)) \
143
 
        config_setting_lookup_string((setting), (key), (const char **) &(var)); \
144
 
    if(var != NULL) var = g_strdup(var);
145
 
 
146
 
gboolean loadConfig(char *filename, CfgFile *lcfg) {
147
 
 
148
 
    config_t hcfg;
149
 
 
150
 
    config_init(&hcfg);
151
 
    if(config_read_file(&hcfg, filename) == CONFIG_FALSE) {
152
 
#ifdef HAVE_LIBCONFIG_ERROR_MACROS
153
 
      const char *efn = config_error_file(&hcfg);
154
 
    g_printerr ("Error reading config file [%s:%d]: %s\n", (efn ? efn : filename), config_error_line(&hcfg), config_error_text(&hcfg));
155
 
#else
156
 
      g_printerr ("Error reading config file %s!\n", filename);
157
 
#endif
158
 
        config_destroy(&hcfg);
159
 
        return (FALSE);
160
 
    }
161
 
 
162
 
#define GETREQ_SETTING_T(varn, sectn) \
163
 
    config_setting_t *(varn) = config_lookup(&hcfg, (sectn)); \
164
 
    if(!(varn)) {                                             \
165
 
        g_error ("Missing section %s in config file %s!", (sectn), filename); \
166
 
        config_destroy(&hcfg); \
167
 
        return (FALSE); \
168
 
    }
169
 
 
170
 
    //    config_setting_t *s_ssh = config_lookup(&hcfg, "SSH");
171
 
    GETREQ_SETTING_T(s_ssh, "SSH");
172
 
    config_setting_t *s_paths = config_lookup(&hcfg, "Paths");
173
 
    config_setting_t *s_screen = config_lookup(&hcfg, "Screen");
174
 
    config_setting_t *s_appearance = config_lookup(&hcfg, "Appearance");
175
 
    config_setting_t *s_notify = config_lookup(&hcfg, "Notify");
176
 
    config_setting_t *s_hooks = config_lookup(&hcfg, "Hooks");
 
132
xmlXPathObjectPtr evalXPath(xmlXPathContextPtr context, const gchar *xpath) {
 
133
  xmlXPathObjectPtr result = xmlXPathEvalExpression(BAD_CAST(xpath), context);
 
134
  if(result == NULL) {
 
135
    g_warning("xmlXPathEvalExpression '%s' failed!\n", xpath);
 
136
    exit(1);
 
137
  }
 
138
 
 
139
  return result;
 
140
}
 
141
 
 
142
char *getXPropStr(const xmlNodePtr nodes[], const gchar *attr, const gchar *defval) {
 
143
  int i;
 
144
  xmlChar *val = NULL;
 
145
 
 
146
  for(i = 0; nodes[i]; i++) {
 
147
    val = xmlGetProp(nodes[i], BAD_CAST(attr));
 
148
 
 
149
    if(val) {
 
150
      gchar *ret = g_strdup((gchar *)val);
 
151
      xmlFree(val);
 
152
      return ret;
 
153
    }
 
154
  }
 
155
 
 
156
  if(defval)
 
157
    return g_strdup(defval);
 
158
 
 
159
  return NULL;
 
160
}
 
161
 
 
162
int getXPropInt(const xmlNodePtr nodes[], const gchar *attr, const int defval) {
 
163
  gchar *sval = getXPropStr(nodes, attr, NULL);
 
164
 
 
165
  if(!sval)
 
166
    return defval;
 
167
 
 
168
  int ival = atoi(sval);
 
169
 
 
170
  g_free(sval);
 
171
 
 
172
  return ival;
 
173
}
 
174
 
 
175
int getXPropBool(const xmlNodePtr nodes[], const gchar *attr, const gboolean defval) {
 
176
  gchar *val = getXPropStr(nodes, attr, NULL);
 
177
  if(!val)
 
178
    return defval;
 
179
 
 
180
  g_strstrip(val);
 
181
 
 
182
  if(g_ascii_strncasecmp(val, "false", 1) == 0 ||
 
183
     g_ascii_strncasecmp(val, "no", 1) == 0) {
 
184
    g_free(val);
 
185
    return FALSE;
 
186
  }
 
187
 
 
188
  if(g_ascii_strncasecmp(val, "true", 1) == 0 ||
 
189
     g_ascii_strncasecmp(val, "yes", 1) == 0) {
 
190
    g_free(val);
 
191
    return TRUE;
 
192
  }
 
193
 
 
194
  if(atoi(val)) {
 
195
    g_free(val);
 
196
    return TRUE;
 
197
  }
 
198
 
 
199
  g_free(val);
 
200
  return FALSE;
 
201
}
 
202
 
 
203
xmlNodeSetPtr getXNodes(xmlXPathContextPtr context, const gchar *xpath) {
 
204
  xmlXPathObjectPtr xobj = xmlXPathEvalExpression(BAD_CAST(xpath), context);
 
205
  xmlNodeSetPtr ret = xobj->nodesetval;
 
206
  xmlXPathFreeNodeSetList(xobj);
 
207
 
 
208
  return ret;
 
209
}
 
210
 
 
211
xmlNodePtr getXNode(xmlXPathContextPtr context, const gchar *xpath) {
 
212
  xmlNodeSetPtr set = getXNodes(context, xpath);
 
213
  xmlNodePtr ret = NULL;
 
214
 
 
215
  if(!xmlXPathNodeSetIsEmpty(set))
 
216
    ret = set->nodeTab[0];
 
217
 
 
218
  xmlXPathFreeNodeSet(set);
 
219
  return ret;
 
220
}
 
221
 
 
222
gboolean loadConfig(const gchar *filename, CfgFile *lcfg) {
 
223
    /* Parse hosts.xml document. */
 
224
    xmlDocPtr xcfg = xmlParseFile(filename);
 
225
    if(xcfg == NULL)
 
226
      return(FALSE);
 
227
 
 
228
    /* Allocate XPath context. */
 
229
    xmlXPathContextPtr xctx = xmlXPathNewContext(xcfg);
 
230
    if(!xctx) {
 
231
      g_error("%s: xmlXPathNewContext failed!\n", filename);
 
232
      return(FALSE);
 
233
    }
 
234
 
 
235
    xmlNodePtr s_ssh[2] = {getXNode(xctx, "/apt-dater/ssh"), NULL};
 
236
    xmlNodePtr s_path[2] = {getXNode(xctx, "/apt-dater/paths"), NULL};
 
237
    xmlNodePtr s_screen[2] = {getXNode(xctx, "/apt-dater/screen"), NULL};
 
238
    xmlNodePtr s_appearance[2] = {getXNode(xctx, "/apt-dater/appearance"), NULL};
 
239
    xmlNodePtr s_notify[2] = {getXNode(xctx, "/apt-dater/notify"), NULL};
 
240
    xmlNodePtr s_hooks[2] = {getXNode(xctx, "/apt-dater/hooks"), NULL};
177
241
#ifdef FEAT_AUTOREF
178
 
    config_setting_t *s_autoref = config_lookup(&hcfg, "AutoRef");
 
242
    xmlNodePtr s_autoref[2] = {getXNode(xctx, "/apt-dater/auto-ref"), NULL};
179
243
#endif
180
244
#ifdef FEAT_HISTORY
181
 
    config_setting_t *s_history = config_lookup(&hcfg, "History");
 
245
    xmlNodePtr s_history[2] = {getXNode(xctx, "/apt-dater/history"), NULL};
182
246
#endif
183
247
#ifdef FEAT_TCLFILTER
184
 
    config_setting_t *s_tclfilter = config_lookup(&hcfg, "TCLFilter");
 
248
    xmlNodePtr s_tclfilter[2] = {getXNode(xctx, "/apt-dater/tcl-filter"), NULL};
185
249
#endif
186
250
 
187
 
    gchar *h;
188
 
    config_setting_lookup_string(s_ssh, "OptionalCmdFlags", (const char **) &h);
189
 
    lcfg->ssh_optflags = (h ? g_strdup(h) : NULL);
 
251
    lcfg->ssh_optflags = getXPropStr(s_ssh, "opt-cmd-flags", NULL);
 
252
    lcfg->ssh_cmd = getXPropStr(s_ssh, "cmd", "/usr/bin/ssh");
 
253
    lcfg->sftp_cmd = getXPropStr(s_ssh, "sftp-cmd", "/usr/bin/sftp");
190
254
 
191
 
    CFG_GET_STRING_DEFAULT(s_paths, "HostsFile", lcfg->hostsfile, g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "hosts.config"));
192
 
    CFG_GET_STRING_DEFAULT(s_paths, "StatsDir", lcfg->statsdir, g_strdup_printf("%s/%s/%s", g_get_user_cache_dir(), PROG_NAME, "stats"));
 
255
    lcfg->hostsfile = getXPropStr(s_path, "hosts-file", g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "hosts.xml"));
 
256
    lcfg->statsdir = getXPropStr(s_path, "stats-dir", g_strdup_printf("%s/%s/%s", g_get_user_cache_dir(), PROG_NAME, "stats"));
193
257
    g_mkdir_with_parents(lcfg->statsdir, S_IRWXU | S_IRWXG | S_IRWXO);
194
258
 
195
 
    CFG_GET_STRING_DEFAULT(s_screen, "RCFile", lcfg->screenrcfile, g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "screenrc"));
196
 
    CFG_GET_STRING_DEFAULT(s_screen, "Title", lcfg->screentitle, g_strdup("%m # %U%H"));
197
 
 
198
 
    h = NULL;
199
 
    if(config_setting_lookup_string(s_ssh, "Cmd", (const char **) &h) == CONFIG_FALSE) {
200
 
        g_printerr ("%s: Config option SSH.Cmd not set!", filename);
201
 
        return (FALSE);
202
 
    }
203
 
    lcfg->ssh_cmd = g_strdup(h);
204
 
 
205
 
    h = NULL;
206
 
    if(config_setting_lookup_string(s_ssh, "SFTPCmd", (const char **) &h) == CONFIG_FALSE) {
207
 
        g_printerr ("%s: Config option SSH.SFTPCmd not set!", filename);
208
 
        return (FALSE);
209
 
    }
210
 
    lcfg->sftp_cmd = g_strdup(h);
211
 
 
212
 
    config_setting_lookup_bool(s_ssh, "SpawnAgent", &(lcfg->ssh_agent));
213
 
 
214
 
    config_setting_t *s_addkeys = config_setting_get_member(s_ssh, "AddKeys");
215
 
    if(s_addkeys != NULL) {
216
 
        if(config_setting_type(s_addkeys) == CONFIG_TYPE_STRING) {
217
 
            lcfg->ssh_add = g_new0(char*, 2);
218
 
            lcfg->ssh_add[0] = g_strdup(config_setting_get_string(s_addkeys));
219
 
        }
220
 
        else if(config_setting_type(s_addkeys) == CONFIG_TYPE_ARRAY) {
221
 
            int len = config_setting_length(s_addkeys);
222
 
            int i;
223
 
 
224
 
            lcfg->ssh_add = g_new0(char*, len + 1);
225
 
            for(i = 0; i<len; i++) {
226
 
                config_setting_t *e = config_setting_get_elem(s_addkeys, i++);
227
 
                lcfg->ssh_add[i] = g_strdup(config_setting_get_string(e));
228
 
            }
229
 
        }
230
 
        else {
231
 
            g_printerr ("%s: setting %s must be a single string or an array of strings", filename, config_setting_name(s_addkeys));
232
 
        }
233
 
    }
234
 
 
235
 
    CFG_GET_BOOL_DEFAULT(s_screen, "NoDumps", lcfg->dump_screen, FALSE);
236
 
    lcfg->dump_screen = !lcfg->dump_screen;
237
 
 
238
 
    CFG_GET_BOOL_DEFAULT(s_screen, "QueryMaintainer", lcfg->query_maintainer, FALSE);
239
 
 
240
 
    h = NULL;
241
 
    if(config_setting_lookup_string(s_appearance, "Colors", (const char **) &h) != CONFIG_FALSE)
242
 
      lcfg->colors = g_strsplit(h, ";", -1);
 
259
    lcfg->screenrcfile = getXPropStr(s_screen, "rc-file", g_strdup_printf("%s/%s/%s", g_get_user_config_dir(), PROG_NAME, "screenrc"));
 
260
    lcfg->screentitle = getXPropStr(s_screen, "title", g_strdup("%m # %U%H"));
 
261
 
 
262
 
 
263
    lcfg->ssh_agent = getXPropBool(s_ssh, "spawn-agent", FALSE);
 
264
 
 
265
    xmlNodeSetPtr s_addkeys = getXNodes(xctx, "/apt-dater/ssh/add-key");
 
266
    if(!xmlXPathNodeSetIsEmpty(s_addkeys)) {
 
267
      lcfg->ssh_add = g_new0(char*, s_addkeys->nodeNr + 1);
 
268
      int i;
 
269
      for(i = 0; i < s_addkeys->nodeNr; i++) {
 
270
        lcfg->ssh_add[i] = g_strdup((gchar *)xmlGetProp(s_addkeys->nodeTab[i], BAD_CAST("name")));
 
271
      }
 
272
    }
 
273
    xmlXPathFreeNodeSet(s_addkeys);
 
274
 
 
275
    lcfg->dump_screen = !getXPropBool(s_screen, "no-dumps", FALSE);
 
276
    lcfg->query_maintainer = getXPropBool(s_screen, "query-maintainer", FALSE);
 
277
 
 
278
    gchar *colors = getXPropStr(s_appearance, "colors", "menu brightgreen blue;status brightgreen blue;selector black red;");
 
279
    if(colors)
 
280
      lcfg->colors = g_strsplit(colors, ";", -1);
243
281
 
244
282
#ifdef FEAT_TCLFILTER
245
 
    config_setting_lookup_string(&s_tclfilter, "FilterExp", &(lcfg->filterexp));
246
 
    config_setting_lookup_string(&s_tclfilter, "FilterFile", &(lcfg->filterfile));
 
283
    lcfg->filterexp = getXPropStr(s_tclfilter, "filter-exp", NULL);
 
284
    lcfg->filterfile = getXPropStr(s_tclfilter, "filter-file", NULL);
247
285
#endif
248
286
 
249
287
#ifdef FEAT_AUTOREF
250
 
    CFG_GET_BOOL_DEFAULT(s_autoref, "Enabled", lcfg->auto_refresh, TRUE);
 
288
    lcfg->auto_refresh = getXPropBool(s_autoref, "enabled", TRUE);
251
289
#endif
252
290
 
253
 
    CFG_GET_BOOL_DEFAULT(s_notify, "Beep", lcfg->beep, TRUE);
254
 
    CFG_GET_BOOL_DEFAULT(s_notify, "Flash", lcfg->flash, TRUE);
 
291
    lcfg->beep = getXPropBool(s_notify, "beep", TRUE);
 
292
    lcfg->flash = getXPropBool(s_notify, "flash", TRUE);
255
293
 
256
294
#ifdef FEAT_HISTORY
257
 
    CFG_GET_BOOL_DEFAULT(s_history, "Record", lcfg->record_history, TRUE);
258
 
    CFG_GET_STRING_DEFAULT(s_history, "ErrPattern", lcfg->history_errpattern, "((?<!no )error|warning|fail)");
 
295
    lcfg->record_history = getXPropBool(s_history, "record", TRUE);
 
296
    lcfg->history_errpattern = getXPropStr(s_history, "err-pattern", "((?<!no )error|warning|fail)");
259
297
#endif
260
298
 
261
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PreUpgrade", lcfg->hook_pre_upgrade, "/etc/apt-dater/pre-upg.d");
262
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PreRefresh", lcfg->hook_pre_refresh, "/etc/apt-dater/pre-ref.d");
263
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PreInstall", lcfg->hook_pre_install, "/etc/apt-dater/pre-ins.d");
264
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PreConnect", lcfg->hook_pre_connect, "/etc/apt-dater/pre-con.d");
265
 
 
266
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PostUpgrade", lcfg->hook_post_upgrade, "/etc/apt-dater/post-upg.d");
267
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PostRefresh", lcfg->hook_post_refresh, "/etc/apt-dater/post-ref.d");
268
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PostInstall", lcfg->hook_post_install, "/etc/apt-dater/post-ins.d");
269
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PostConnect", lcfg->hook_post_connect, "/etc/apt-dater/post-con.d");
270
 
 
271
 
    CFG_GET_STRING_DEFAULT(s_hooks, "PluginDir", lcfg->plugindir, "/etc/apt-dater/plugins");
272
 
 
273
 
 
274
 
    config_destroy(&hcfg);
 
299
    lcfg->hook_pre_upgrade = getXPropStr(s_hooks, "pre-upgrade", "/etc/apt-dater/pre-upg.d");
 
300
    lcfg->hook_pre_refresh = getXPropStr(s_hooks, "pre-refresh", "/etc/apt-dater/pre-ref.d");
 
301
    lcfg->hook_pre_install = getXPropStr(s_hooks, "pre-install", "/etc/apt-dater/pre-ins.d");
 
302
    lcfg->hook_pre_connect = getXPropStr(s_hooks, "pre-connect", "/etc/apt-dater/pre-con.d");
 
303
 
 
304
    lcfg->hook_post_upgrade = getXPropStr(s_hooks, "post-upgrade", "/etc/apt-dater/post-upg.d");
 
305
    lcfg->hook_post_refresh = getXPropStr(s_hooks, "post-refresh", "/etc/apt-dater/post-ref.d");
 
306
    lcfg->hook_post_install = getXPropStr(s_hooks, "post-install", "/etc/apt-dater/post-ins.d");
 
307
    lcfg->hook_post_connect = getXPropStr(s_hooks, "post-connect", "/etc/apt-dater/post-con.d");
 
308
 
 
309
    lcfg->plugindir = getXPropStr(s_hooks, "plugin-dir", "/etc/apt-dater/plugins");
 
310
 
275
311
    return (TRUE);
276
312
}
277
313
 
278
 
#define HCFG_GET_STRING(setting,var,def) \
279
 
    var = (def); \
280
 
    if(config_setting_lookup_string( cfghost, (setting), (const char **) &var) == CONFIG_FALSE) \
281
 
    if(config_setting_lookup_string(cfggroup, (setting), (const char **) &var) == CONFIG_FALSE) \
282
 
    config_setting_lookup_string(cfghosts, (setting), (const char **) &var); \
283
 
    if(var != NULL) var = g_strdup(var)
284
 
 
285
 
#define HCFG_GET_INT(setting,var,def) \
286
 
    var = (def); \
287
 
    if(config_setting_lookup_int( cfghost, (setting), &var) == CONFIG_FALSE) \
288
 
    if(config_setting_lookup_int(cfggroup, (setting), &var) == CONFIG_FALSE) \
289
 
    config_setting_lookup_int(cfghosts, (setting), &var)
290
 
 
291
 
GList *loadHosts (const char *filename) {
292
 
    config_t hcfg;
293
 
 
294
 
    config_init(&hcfg);
295
 
    if(config_read_file(&hcfg, filename) == CONFIG_FALSE) {
296
 
#ifdef HAVE_LIBCONFIG_ERROR_MACROS
297
 
      const char *efn = config_error_file(&hcfg);
298
 
      g_printerr ("Error reading host file [%s:%d]: %s\n", (efn ? efn : filename), config_error_line(&hcfg), config_error_text(&hcfg));
299
 
#else
300
 
      g_printerr ("Error reading host file %s!\n", filename);
301
 
#endif
302
 
        config_destroy(&hcfg);
303
 
        return (FALSE);
304
 
    }
305
 
 
306
 
    config_setting_t *cfghosts = config_lookup(&hcfg, "Hosts");
307
 
    if(cfghosts == NULL) {
308
 
        g_printerr ("%s: No Hosts entries found.\n", filename);
309
 
        config_destroy(&hcfg);
310
 
        return (FALSE);
311
 
    }
312
 
 
313
 
    GList *hosts = NULL;
 
314
GList *loadHosts (const gchar *filename) {
 
315
    /* Parse hosts.xml document. */
 
316
    xmlDocPtr xcfg = xmlParseFile(filename);
 
317
    if(xcfg == NULL)
 
318
      return(FALSE);
 
319
 
 
320
    /* Allocate XPath context. */
 
321
    xmlXPathContextPtr xctx = xmlXPathNewContext(xcfg);
 
322
    if(!xctx) {
 
323
      g_error("%s: xmlXPathNewContext failed!\n", filename);
 
324
      return(FALSE);
 
325
    }
 
326
 
 
327
    /* Lookup global host template node. */
 
328
    xmlXPathObjectPtr defaults = evalXPath(xctx, "/hosts/default");
 
329
    xmlNodePtr defhost = NULL;
 
330
    if(!xmlXPathNodeSetIsEmpty(defaults->nodesetval))
 
331
      defhost = defaults->nodesetval->nodeTab[0];
 
332
    xmlXPathFreeObject(defaults);
 
333
 
 
334
    /* Iterate over /hosts/group nodes. */
 
335
    xmlXPathObjectPtr groups = evalXPath(xctx, "/hosts/group");
314
336
    int i;
315
 
    config_setting_t *cfggroup;
316
 
    for(i=0; (cfggroup = config_setting_get_elem(cfghosts, i)); i++) {
317
 
        int j;
318
 
        gchar *group;
319
 
        CFG_GET_STRING_DEFAULT(cfggroup, "Title", group, config_setting_name(cfggroup));
320
 
 
321
 
        config_setting_t *cfghost;
322
 
        for(j=0; (cfghost = config_setting_get_elem(cfggroup, j)); j++) {
323
 
            if(cfghost->type != CONFIG_TYPE_GROUP)
324
 
              continue;
325
 
 
326
 
            HostNode *hostnode = g_new0(HostNode, 1);
 
337
    GList *hostlist = NULL;
 
338
    for(i = 0; i < groups->nodesetval->nodeNr; i++) {
 
339
      xmlNodePtr group = groups->nodesetval->nodeTab[i];
 
340
 
 
341
      xmlChar *groupname = xmlGetProp(group, BAD_CAST("name"));
 
342
      if(!groupname) {
 
343
        g_printerr("%s: The group element #%d does not have a name attribute!\n", filename, i+1);
 
344
        return(FALSE);
 
345
      }
 
346
 
 
347
      xctx->node = group;
 
348
      xmlXPathObjectPtr hosts = evalXPath(xctx, "host");
 
349
      if(xmlXPathNodeSetIsEmpty(hosts->nodesetval)) {
 
350
        xmlXPathFreeObject(hosts);
 
351
        xmlFree(groupname);
 
352
        g_warning("%s: The group '%s' is empty!\n", filename, groupname);
 
353
        continue;
 
354
      }
 
355
 
 
356
      /* Iterate over /hosts/group/host nodes. */
 
357
      int j;
 
358
      for(j = 0; j < hosts->nodesetval->nodeNr; j++) {
 
359
        xmlNodePtr host = hosts->nodesetval->nodeTab[j];
 
360
        xmlNodePtr cfgnodes[4] = {host, group, defhost, NULL};
 
361
 
 
362
        xmlChar *hostname = xmlGetProp(host, BAD_CAST("name"));
 
363
        if(!hostname) {
 
364
          g_printerr("%s: The host element #%d of group '%s' does not have a name attribute!\n", filename, j+1, groupname);
 
365
 
 
366
          xmlXPathFreeObject(hosts);
 
367
          xmlXPathFreeObject(groups);
 
368
          xmlFree(groupname);
 
369
          return(FALSE);
 
370
        }
 
371
 
 
372
        HostNode *hostnode = g_new0(HostNode, 1);
327
373
#ifndef NDEBUG
328
 
            hostnode->_type = T_HOSTNODE;
 
374
        hostnode->_type = T_HOSTNODE;
329
375
#endif
330
 
            hostnode->hostname = g_strdup(cfghost->name);
331
 
            HCFG_GET_STRING("Comment", hostnode->comment, NULL);
332
 
            HCFG_GET_STRING("Type", hostnode->type, "generic-ssh");
333
 
            HCFG_GET_STRING("SSHUser", hostnode->ssh_user, NULL);
334
 
            HCFG_GET_STRING("SSHHost", hostnode->ssh_host, NULL);
335
 
            HCFG_GET_INT("SSHPort", hostnode->ssh_port, 0);
336
 
            HCFG_GET_STRING("SSHIdentity", hostnode->identity_file, NULL);
337
 
 
338
 
            hostnode->group = g_strdup(group);
339
 
 
340
 
            hostnode->statsfile = g_strdup_printf("%s/%s:%d.stat", cfg->statsdir, hostnode->hostname, hostnode->ssh_port);
341
 
            hostnode->fdlock = -1;
342
 
            hostnode->uuid[0] = 0;
343
 
            hostnode->tagged = FALSE;
344
 
 
345
 
            getUpdatesFromStat(hostnode);
346
 
 
347
 
            hosts = g_list_append(hosts, hostnode);
348
 
        }
 
376
        hostnode->hostname = g_strdup((gchar *)hostname);
 
377
        hostnode->comment = getXPropStr(cfgnodes, "comment", NULL);
 
378
        hostnode->type = getXPropStr(cfgnodes, "type", "generic-ssh");
 
379
        hostnode->ssh_user = getXPropStr(cfgnodes, "ssh-user", NULL);
 
380
        hostnode->ssh_host = getXPropStr(cfgnodes, "ssh-host", NULL);
 
381
        hostnode->ssh_port = getXPropInt(cfgnodes, "ssh-port", 0);
 
382
        hostnode->identity_file = getXPropStr(cfgnodes, "ssh-id", NULL);
 
383
 
 
384
        hostnode->group = g_strdup((gchar *)groupname);
 
385
 
 
386
        hostnode->statsfile = g_strdup_printf("%s/%s:%d.stat", cfg->statsdir, hostnode->hostname, hostnode->ssh_port);
 
387
        hostnode->fdlock = -1;
 
388
        hostnode->uuid[0] = 0;
 
389
        hostnode->tagged = FALSE;
 
390
 
 
391
        getUpdatesFromStat(hostnode);
 
392
 
 
393
        hostlist = g_list_append(hostlist, hostnode);
 
394
 
 
395
        xmlFree(hostname);
 
396
      }
 
397
 
 
398
      xmlXPathFreeObject(hosts);
 
399
      xmlFree(groupname);
349
400
    }
350
401
 
351
 
    config_destroy(&hcfg);
352
 
    return hosts;
 
402
    xmlXPathFreeObject(groups);
 
403
    return hostlist;
353
404
}