*/
static int flt_ot_parse_cfg(struct flt_ot_conf *conf, const char *flt_name, char **err)
{
- struct list backup_sections;
- int retval = ERR_ABORT | ERR_ALERT;
+ struct list backup_sections;
+ struct cfgfile cfg_file = {0};
+ int retval = ERR_ABORT | ERR_ALERT;
FLT_OT_FUNC("%p, \"%s\", %p:%p", conf, flt_name, FLT_OT_DPTR_ARGS(err));
/* Do nothing. */;
else if (access(conf->cfg_file, R_OK) == -1)
FLT_OT_PARSE_ERR(err, "'%s' : %s", conf->cfg_file, strerror(errno));
- else
- retval = readcfgfile(conf->cfg_file);
+ else {
+ cfg_file.filename = conf->cfg_file;
+ cfg_file.size = load_cfg_in_mem(cfg_file.filename, &cfg_file.content);
+ if (cfg_file.size < 0) {
+ ha_free(&cfg_file.content);
+ FLT_OT_RETURN_INT(retval);
+ }
+ retval = readcfgfile(&cfg_file);
+ ha_free(&cfg_file.content);
+ }
/* Unregister OT sections and restore previous sections. */
cfg_unregister_sections();
int cfg_parse_listen(const char *file, int linenum, char **args, int inv);
int cfg_parse_track_sc_num(unsigned int *track_sc_num,
const char *arg, const char *end, char **err);
-int readcfgfile(const char *file);
+int readcfgfile(const struct cfgfile *cfg);
void cfg_register_keywords(struct cfg_kw_list *kwl);
void cfg_unregister_keywords(struct cfg_kw_list *kwl);
int check_config_validity(void);
}
/*
- * This function reads and parses the configuration file given in the argument.
- * Returns the error code, 0 if OK, -1 if the config file couldn't be opened,
+ * This function parses the configuration file given in the argument.
+ * Returns the error code, 0 if OK, -1 if we are run out of memory,
* or any combination of :
* - ERR_ABORT: must abort ASAP
* - ERR_FATAL: we can continue parsing but not start the service
* Only the two first ones can stop processing, the two others are just
* indicators.
*/
-int readcfgfile(const char *file)
+int readcfgfile(const struct cfgfile *cfg)
{
char *thisline = NULL;
int linesize = LINESIZE;
- FILE *f = NULL;
int linenum = 0;
int err_code = 0;
struct cfg_section *cs = NULL, *pcs = NULL;
int nested_cond_lvl = 0;
enum nested_cond_state nested_conds[MAXNESTEDCONDS];
char *errmsg = NULL;
+ const char *cur_position = cfg->content;
+ char *file = cfg->filename;
global.cfg_curr_line = 0;
global.cfg_curr_file = file;
goto err;
}
- if ((f = fopen(file,"r")) == NULL) {
- err_code = -1;
- goto err;
- }
-
/* change to the new dir if required */
if (!cfg_apply_default_path(file, NULL, &errmsg)) {
ha_alert("parsing [%s:%d]: failed to apply default-path: %s.\n", file, linenum, errmsg);
}
next_line:
- while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
+ while (fgets_from_mem(thisline + readbytes, linesize - readbytes,
+ &cur_position, cfg->content + cfg->size)) {
int arg, kwm = KWM_STD;
char *end;
char *args[MAX_LINE_ARGS + 1];
global.cfg_curr_line = 0;
global.cfg_curr_file = NULL;
- if (f)
- fclose(f);
-
return err_code;
}
struct spoe_group *grp, *grpback;
struct spoe_placeholder *ph, *phback;
struct spoe_var_placeholder *vph, *vphback;
+ struct cfgfile cfg_file = {0};
struct logger *logger, *loggerback;
char *file = NULL, *engine = NULL;
int ret, pos = *cur_arg + 1;
curengine = engine;
curagent = NULL;
curmsg = NULL;
- ret = readcfgfile(file);
+
+ /* load the content of SPOE config file from cfg_file.filename into some
+ * area in .heap. readcfgfile() now parses the content of config files
+ * stored in RAM as separate chunks (see struct cfgfile in cfgparse.h),
+ * these chunks chained in cfg_cfgfiles global list.
+ */
+ cfg_file.filename = file;
+ cfg_file.size = load_cfg_in_mem(file, &cfg_file.content);
+ if (cfg_file.size < 0) {
+ goto error;
+ }
+ ret = readcfgfile(&cfg_file);
+ ha_free(&cfg_file.content);
/* unregister SPOE sections and restore previous sections */
cfg_unregister_sections();
return 0;
error:
+ ha_free(&cfg_file.content);
spoe_release_agent(curagent);
list_for_each_entry_safe(ph, phback, &curmphs, list) {
LIST_DELETE(&ph->list);
static int read_cfg(char *progname)
{
char *env_cfgfiles = NULL;
- struct cfgfile *cfg;
+ struct cfgfile *cfg, *cfg_tmp;
int err_code = 0;
/* handle cfgfiles that are actually directories */
setenv("HAPROXY_HTTPS_LOG_FMT", default_https_log_format, 1);
setenv("HAPROXY_TCP_LOG_FMT", default_tcp_log_format, 1);
setenv("HAPROXY_BRANCH", PRODUCT_BRANCH, 1);
- list_for_each_entry(cfg, &cfg_cfgfiles, list) {
+ list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {
int ret;
+ cfg->size = load_cfg_in_mem(cfg->filename, &cfg->content);
+ if (cfg->size < 0)
+ goto err;
+
if (!memprintf(&env_cfgfiles, "%s%s%s",
(env_cfgfiles ? env_cfgfiles : ""),
(env_cfgfiles ? ";" : ""), cfg->filename)) {
goto err;
}
- ret = readcfgfile(cfg->filename);
+ ret = readcfgfile(cfg);
if (ret == -1)
goto err;