From 5b9ed6e4bede716dfcf53d1d488dc15701bceac8 Mon Sep 17 00:00:00 2001 From: Valentine Krasnobaeva Date: Mon, 5 Aug 2024 10:03:39 +0200 Subject: [PATCH] MINOR: cfgparse: add load_cfg_in_mem Add load_cfg_in_mem() helper, which allows to store the content of a given file in memory. --- include/haproxy/cfgparse.h | 1 + src/cfgparse.c | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/haproxy/cfgparse.h b/include/haproxy/cfgparse.h index efb4cbe7c..6033b421e 100644 --- a/include/haproxy/cfgparse.h +++ b/include/haproxy/cfgparse.h @@ -141,6 +141,7 @@ int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, const int failifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint); void cfg_dump_registered_keywords(); int list_append_cfgfile(struct list *li, const char *filename, char **err); +ssize_t load_cfg_in_mem(char* filename, char** cfg_content); /* simplified way to define a section parser */ #define REGISTER_CONFIG_SECTION(name, parse, post) \ diff --git a/src/cfgparse.c b/src/cfgparse.c index 6942ccb38..bbaab7636 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1750,6 +1750,58 @@ fail_entry: return 0; } +/* loads the content of the given file in memory. On success, returns the number + * of bytes successfully stored at *cfg_content until EOF. On error, emits + * alerts, performs needed clean-up routines and returns -1. + */ +ssize_t load_cfg_in_mem(char *filename, char **cfg_content) +{ + size_t bytes_to_read = LINESIZE; + size_t chunk_size = 0; + size_t read_bytes = 0; + char *new_area; + size_t ret = 0; + FILE *f; + + if ((f = fopen(filename,"r")) == NULL) { + ha_alert("Could not open configuration file %s : %s\n", + filename, strerror(errno)); + return -1; + } + + *cfg_content = NULL; + + while (1) { + if (read_bytes + bytes_to_read > chunk_size) { + chunk_size = (read_bytes + bytes_to_read) * 2; + new_area = realloc(*cfg_content, chunk_size); + if (new_area == NULL) { + ha_alert("Loading %s: file too long, cannot allocate memory.\n", + filename); + goto free_mem; + } + *cfg_content = new_area; + } + + bytes_to_read = chunk_size - read_bytes; + ret = fread(*cfg_content + read_bytes, sizeof(char), bytes_to_read, f); + read_bytes += ret; + + if (!ret || feof(f) || ferror(f)) + break; + } + + fclose(f); + + return read_bytes; + +free_mem: + ha_free(cfg_content); + fclose(f); + + return -1; +} + /* * 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,